/*
 * Bt Framework
 * Copyright(c) 2009, Bruno Tavares.
 */


Ext.override(Ext.Component, {

	// ----- SITEMAP ----- //
		
		
		redirect: function( _class, cfg , callback , scope )
		{
			if( this.onBeforeRedirect && this.onBeforeRedirect() === false )
				return;
				
			if( typeof _class === 'string' )
			{
				if( window[_class] )
				{	
					eval('_class=' + _class);
				}
				else
				{
					var params 	= Array.prototype.slice.call(arguments,0);
					Bt.require(_class,function(){ this.redirect.apply(this,params);},this);
					return;
				}
			}	
			
			cfg = cfg||{};
			
			//guarda estrutura do atual
			cfg.previousCmpConfig = this.initialConfig;
			
			//guarda dados importantes
			cfg.previousCmpConfig.title 			= this.title;
			cfg.previousCmpConfig.navigationTitle 	= this.navigationTitle; 
			cfg.previousCmpConfig.xtype				= this.getXType();
			cfg.previousCmpConfig.constructor		= this.constructor;
			
			//mant�m caminho
			cfg.previousCmpConfig.previousCmpConfig = this.previousCmpConfig;
			
			//cria instancia
			var _instance = new _class(cfg);
			
			//guarda owner
			var ownerCt = this.ownerCt;
			
			//retira atual
			ownerCt.remove(this);
	
			//coloca o novo
			ownerCt.add( _instance );
			
			//refaz layout
			if(ownerCt.layout)
				ownerCt.doLayout();
			
			//calback
			if(callback)
				callback.apply(scope||this,[_instance]);
			
			if( this.onRedirect )
				this.onRedirect();
					
			//retorna novo cmp
			return _instance;
		}
		
		
		,redirectBack: function(steps)
		{
			if( this.onBeforeRedirectBack && this.onBeforeRedirectBack() === false )
				return;
						
			steps 	= steps||1;
			var cmp = this;
			
			while( steps != 0 )
			{
				if(!cmp.previousCmpConfig)
					break;
					
				cmp = cmp.previousCmpConfig
				steps--;
			}
			
			if(cmp === this)
			 	return;
				
			//busca estrutura do anterior
			var config = cmp;
				
			//guarda owner
			var ownerCt = this.ownerCt;
			
			//retira atual
			ownerCt.remove(this);
			
			//coloca o novo
			var _instance = ownerCt.add( config.xtype ? config : new config.constructor(config) );
			
			//refaz layout
			if(ownerCt.layout)
				ownerCt.doLayout();
			
			if( this.onRedirectBack )
				this.onRedirectBack();
				
			//retorna novo cmp
			return _instance;
		}
		
		
		,getNavigation: function()
		{
			var cmp  	= this;
			var items	= [];
			var i 		= 0;
			
			while( cmp )
			{
				navigationTitle = cmp.navigationTitle||cmp.title;
				navigationTitle += '';
				
				if(navigationTitle)
				{
					navigationTitle = 	navigationTitle.substr( navigationTitle.length-1 , navigationTitle.length) == '$' ? 
										navigationTitle.substr(0,navigationTitle.length-1) : 
										Ext.util.Format.ellipsis(navigationTitle,30)
				}
				
				if( items.length === 0 )
				{
					items.unshift('<span class="bt-breadcrumb-text" id="'+(this.siteMapTextID=Ext.id())+'">'+ navigationTitle +'</span>');
				}
				else
				{
					items.unshift({
						 text	: navigationTitle
						,cls	: 'bt-breadcrumb-link'
						,scope	: this
						,handler: function(j)
						{
							return function(){ this.redirectBack(j); }
						}(i)				
					});
				}
				
				cmp = cmp.previousCmpConfig;
				i++;
				
				if( cmp )
					items.unshift('<img src="'+Ext.BLANK_IMAGE_URL+'" class="bt-breadcrumb-arrow" width="5" height="10" />');
			}
			
			if( items.length === 1 )
			{
				//hack para manter altura
				items.push({	   
					 text	: '&nbsp;'
					,style	: 'visibility:hidden; width:1px;'
				});
			}
			
			//empurra todo o resto pro fim
			items.push('->');
			
			return items;
		}	
		
		
		,updateSiteMap : function(title)
		{
			if(title)
				this.navigationTitle = title;
			
			var elSpan = Ext.get(this.siteMapTextID);
			
			if(elSpan)
			{
				elSpan.update(Ext.util.Format.ellipsis(this.navigationTitle||this.title,30))
			}
		}
});
Ext.override(Ext.Element,{
	
	
	setLoading:function( isLoading , cfg )
	{
		if( isLoading )
		{
			cfg = Ext.applyIf(cfg||{},{
				 text	:Ext.LoadMask.prototype.msg
				,simple	:false
			})
			
			if(this.is('input'))
			{
				this._maskWrap = this.wrap();
				this._maskWrap.mask( cfg.text , 'bt-mask-loading'  );
			}
			else
			{
				var cls = cfg.simple ? 'bt-mask-loading':'x-mask-loading'
				
				if(cfg.opaque == true)
					this.addClass('bt-opaque');
				
				this.mask( cfg.text , cls  )
			}
		}
		else
		{
			if(this._maskWrap)
			{
				this.appendTo( this._maskWrap.parent() );
				this._maskWrap.remove();
			}
			else
			{
				this.unmask();
			}
			
			this.removeClass('bt-opaque');
		}
	}
});
Ext.override(Ext.form.Field,{
	
		
	 setReadOnly: function(readOnly)
	 {
	 	this.readOnly = readOnly;
		
		if(this.el)
		{
			var type = this.el.dom.type||"text";
			if(type == 'password')
			    type = 'text';
		
			this.el.dom.readOnly = readOnly;
			this.el[readOnly ? 'addClass' : 'removeClass']('x-form-'+type+'-readonly');
		}
	 }
	 
});



Ext.form.Field.prototype.onRender = Ext.form.Field.prototype.onRender.createSequence(function()
{
	var type = this.el.dom.type||"text";
    if(type == 'password')
        type = 'text';
	
	if(this.readOnly)
        this.el.addClass('x-form-'+type+'-readonly');
});


Ext.ns('Ext.ux.form');


Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField,  {
    
    buttonText: 'Browse...',
    
    buttonOnly: false,
    
    buttonOffset: 3,
    

    // private
    readOnly: true,

    
    autoSize: Ext.emptyFn,
	
	allowedExtensions: undefined,

    // private
    initComponent: function(){
        Ext.ux.form.FileUploadField.superclass.initComponent.call(this);

        this.addEvents(
            
            'fileselected'
        );
    },

    // private
    onRender : function(ct, position){
        Ext.ux.form.FileUploadField.superclass.onRender.call(this, ct, position);

        this.wrap = this.el.wrap({cls:'x-form-field-wrap x-form-file-wrap'});
        this.el.addClass('x-form-file-text');
        this.el.dom.removeAttribute('name');

        this.fileInput = this.wrap.createChild({
            id: this.getFileInputId(),
            name: this.name||this.getId(),
            cls: 'x-form-file',
            tag: 'input',
            type: 'file',
            size: 1
        });

        var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
            text: this.buttonText
        });
        this.button = new Ext.Button(Ext.apply(btnCfg, {
            renderTo: this.wrap,
            cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '')
        }));

        if(this.buttonOnly){
            this.el.hide();
            this.wrap.setWidth(this.button.getEl().getWidth());
        }

        this.fileInput.on('change', function(){
            var v = this.fileInput.dom.value;
			
			if( this.allowedExtensions )
			{
				var ext = v.split('.')
				ext = ext[ext.length-1].toUpperCase();
				
				if( ("," + this.allowedExtensions.join(',').toUpperCase() + ",").indexOf(","+ext+",") == -1)
				{
					this.reset();
					this.markInvalid("Extens&#245;es permitidas: " + this.allowedExtensions.join(', '));
					return false;	
				}
			}
			
			
            this.setValue(v);
            this.fireEvent('fileselected', this, v);
        }, this);
    },
	
	reset: function()
	{ 
		Ext.ux.form.FileUploadField.superclass.reset.apply(this,arguments);
		this.fileInput.dom.value = "";
	},

    // private
    getFileInputId: function(){
        return this.id + '-file';
    },

    // private
    onResize : function(w, h){

        Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);

        this.wrap.setWidth(w);

        if(!this.buttonOnly){
            var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset;
            this.el.setWidth(w);
        }
    },

    // private
    onDestroy: function(){
        Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
        Ext.destroy(this.fileInput, this.button, this.wrap);
    },


    // private
    preFocus : Ext.emptyFn,

    // private
    getResizeEl : function(){
        return this.wrap;
    },

    // private
    getPositionEl : function(){
        return this.wrap;
    },

    // private
    alignErrorIcon : function(){
        this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
    }

});

Ext.reg('filefield', Ext.ux.form.FileUploadField);
Ext.namespace('Ext.ux.netbox');

//Override
Ext.form.TextField.prototype.initComponent = Ext.form.TextField.prototype.initComponent.createSequence(function()
{
	if( this.vmask )
	{
		this.inputMask = Bt.form.VMask[this.vmask];
		delete this.vmask;
	}
	
	if( this.inputMask )
	{
		var plugin =  {
			 ptype	: 'inputmask'
			,mask	: this.inputMask
		}  
		
		delete this.inputMask;
		
		if(!this.plugins)
		{
			this.plugins = plugin;
		}
		else if( Ext.isArray(this.plugins) )
		{
			this.plugins.push(plugin);
		}
		else
		{
			this.plugins = [this.plugins,plugin];
		}
	}
});

Ext.override(Ext.form.TextField,{
	setValue: function(v)
	{
		if( this.maskPlugin && v.length !== 0 )
		{
			var mask = this.maskPlugin.rawMask;
			var specialReg = this.maskPlugin.specialChars;
		
			for( var init, end, i = 0, charMask, charValue ; i < mask.length ; i++ )
			{
				charMask = mask.charAt(i);
				
				if( specialReg.indexOf(charMask		) !== -1 && 
					specialReg.indexOf(v.charAt(i)	) === -1 
				)
				{
					init = v.substring(0,i);
					end  = v.substring(i);
					v = init + charMask + end;
				}
				else if( v.length - 1 < i)
				{
					v += '_';
				}
			}
		}
		
		if(this.emptyText && this.el && !Ext.isEmpty(v)){
	        this.el.removeClass(this.emptyClass);
	    }
	    Ext.form.TextField.superclass.setValue.apply(this, arguments);
	    this.applyEmptyText();
	    this.autoSize();
	    return this;
	}
});	


Ext.ux.netbox.InputTextMask = function(mask,clearWhenInvalid) {
	
	if(Ext.isObject(mask))
	{
		clearWhenInvalid = mask.clearWhenInvalid;
		mask = mask.mask;
	}
	
	//inits
    this.clearWhenInvalid = clearWhenInvalid||false;
    this.rawMask = mask;
    this.viewMask = '';
    this.maskArray = new Array();
   
    var mai = 0;
    var regexp = '';
    for(var i=0; i<mask.length; i++)
	{
        if(regexp){
            if(regexp == 'X'){
                regexp = '';
            }
            if(mask.charAt(i) == 'X'){
                this.maskArray[mai] = regexp;
                mai++;
                regexp = '';
            } else {
                regexp += mask.charAt(i);
            }
        } else if(mask.charAt(i) == 'X'){
            regexp += 'X';
            this.viewMask += '_';
        } else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
            this.viewMask += '_';
            this.maskArray[mai] = mask.charAt(i);
            mai++;
        } else {
            this.viewMask += mask.charAt(i);
            this.maskArray[mai] = RegExp.escape(mask.charAt(i));
            mai++;
        }
    }

    this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
};

Ext.ux.netbox.InputTextMask.prototype = {

    init : function(field) {
        this.field = field;
		
		field.maskPlugin = this;
		field.on('destroy',function(){ delete field.maskPlugin; });
		
        field.afterRender = field.afterRender.createSequence(this.assignEl,this);
        field.onBlur = field.onBlur.createInterceptor(this.removeValueWhenInvalid,this);
        field.on('focus',this.processMaskFocus, this);
    }

    ,assignEl : function() 
	{
        this.inputTextElement = this.field.getEl().dom;
        
		this.field.getEl().on('keypress', this.processKeyPress, this);
        this.field.getEl().on('keydown', this.processKeyDown, this);
		
        if(Ext.isSafari || Ext.isIE)
		{
            this.field.getEl().on('paste',this.startTask,this);
            this.field.getEl().on('cut',this.startTask,this);
        }
        else if(Ext.isGecko || Ext.isOpera)
		{
            this.field.getEl().on('mousedown',this.setPreviousValue,this);
        }
        
		if(Ext.isGecko)
		{
          this.field.getEl().on('input',this.onInput,this);
        }
		else if(Ext.isOpera)
		{
          this.field.getEl().on('input',this.onInputOpera,this);
        }
    }
	
    ,onInput : function(){
        this.startTask(false);
    },
    onInputOpera : function(){
      if(!this.prevValueOpera){
        this.startTask(false);
      }else{
        this.manageBackspaceAndDeleteOpera();
      }
    },
    
    manageBackspaceAndDeleteOpera: function(){
      this.inputTextElement.value=this.prevValueOpera.cursorPos.previousValue;
      this.manageTheText(this.prevValueOpera.keycode,this.prevValueOpera.cursorPos);
      this.prevValueOpera=null;
    },

    setPreviousValue : function(event){
        this.oldCursorPos=this.getCursorPosition();
    },

    getValidatedKey : function(keycode, cursorPosition) {
        var maskKey = this.maskArray[cursorPosition.start];
        if(maskKey == '9'){
            return keycode.pressedKey.match(/[0-9]/);
        } else if(maskKey == 'L'){
            return (keycode.pressedKey.match(/[A-Za-z]/))? keycode.pressedKey.toUpperCase(): null;
        } else if(maskKey == 'l'){
            return (keycode.pressedKey.match(/[A-Za-z]/))? keycode.pressedKey.toLowerCase(): null;
        } else if(maskKey == 'A'){
            return keycode.pressedKey.match(/[A-Za-z0-9]/);
        } else if(maskKey){
            return (keycode.pressedKey.match(new RegExp(maskKey)));
        }
        return(null);
    },

    removeValueWhenInvalid : function() 
	{
        if(
			(this.inputTextElement.value === this.viewMask) || 
			(this.clearWhenInvalid && this.inputTextElement.value.indexOf('_') > -1)
		){
            this.inputTextElement.value = '';
        }
    },

    managePaste : function() {
        if(this.oldCursorPos==null){
          return;
        }
        var valuePasted=this.inputTextElement.value.substring(this.oldCursorPos.start,this.inputTextElement.value.length-(this.oldCursorPos.previousValue.length-this.oldCursorPos.end));
        if(this.oldCursorPos.start<this.oldCursorPos.end){//there is selection...
          this.oldCursorPos.previousValue=
            this.oldCursorPos.previousValue.substring(0,this.oldCursorPos.start)+
            this.viewMask.substring(this.oldCursorPos.start,this.oldCursorPos.end)+
            this.oldCursorPos.previousValue.substring(this.oldCursorPos.end,this.oldCursorPos.previousValue.length);
          valuePasted=valuePasted.substr(0,this.oldCursorPos.end-this.oldCursorPos.start);
        }
        this.inputTextElement.value=this.oldCursorPos.previousValue;
        keycode={unicode :'',
        isShiftPressed: false,
        isTab: false,
        isBackspace: false,
        isLeftOrRightArrow: false,
        isDelete: false,
        pressedKey : ''
        }
        var charOk=false;
        for(var i=0;i<valuePasted.length;i++){
            keycode.pressedKey=valuePasted.substr(i,1);
            keycode.unicode=valuePasted.charCodeAt(i);
            this.oldCursorPos=this.skipMaskCharacters(keycode,this.oldCursorPos);
            if(this.oldCursorPos===false){
                break;
            }
            if(this.injectValue(keycode,this.oldCursorPos)){
                charOk=true;
                this.moveCursorToPosition(keycode, this.oldCursorPos);
                this.oldCursorPos.previousValue=this.inputTextElement.value;
                this.oldCursorPos.start=this.oldCursorPos.start+1;
            }
        }
        if(!charOk && this.oldCursorPos!==false){
            this.moveCursorToPosition(null, this.oldCursorPos);
        }
        this.oldCursorPos=null;
    },

    processKeyDown : function(e){
        this.processMaskFormatting(e,'keydown');
    },

    processKeyPress : function(e){
        this.processMaskFormatting(e,'keypress');
    },

    startTask : function(setOldCursor){
        if(this.task==undefined){
            this.task=new Ext.util.DelayedTask(this.managePaste,this);
      }
        if(setOldCursor!== false){
            this.oldCursorPos=this.getCursorPosition();
      }
      this.task.delay(0);
    },

    skipMaskCharacters : function(keycode, cursorPos){
        if(cursorPos.start!=cursorPos.end && (keycode.isDelete || keycode.isBackspace))
            return(cursorPos);
        while(this.specialChars.match(RegExp.escape(this.viewMask.charAt(((keycode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
            if(keycode.isBackspace) {
                cursorPos.dec();
            } else {
                cursorPos.inc();
            }
            if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
                return false;
            }
        }
        return(cursorPos);
    },

    isManagedByKeyDown : function(keycode){
        if(keycode.isDelete || keycode.isBackspace){
            return(true);
        }
        return(false);
    },

    processMaskFormatting : function(e, type) {
        this.oldCursorPos=null;
        var cursorPos = this.getCursorPosition();
        var keycode = this.getKeyCode(e, type);
        if(keycode.unicode==0){//?? sometimes on Safari
            return;
        }
        if((keycode.unicode==67 || keycode.unicode==99) && e.ctrlKey){//Ctrl+c, let's the browser manage it!
            return;
        }
        if((keycode.unicode==88 || keycode.unicode==120) && e.ctrlKey){//Ctrl+x, manage paste
            this.startTask();
            return;
        }
        if((keycode.unicode==86 || keycode.unicode==118) && e.ctrlKey){//Ctrl+v, manage paste....
            this.startTask();
            return;
        }
        if((keycode.isBackspace || keycode.isDelete) && Ext.isOpera){
          this.prevValueOpera={cursorPos: cursorPos, keycode: keycode};
          return;
        }
        if(type=='keydown' && !this.isManagedByKeyDown(keycode)){
            return true;
        }
        if(type=='keypress' && this.isManagedByKeyDown(keycode)){
            return true;
        }
        if(this.handleEventBubble(e, keycode, type)){
            return true;
        }
        return(this.manageTheText(keycode, cursorPos));
    },
    
    manageTheText: function(keycode, cursorPos){
      if(this.inputTextElement.value.length === 0){
          this.inputTextElement.value = this.viewMask;
      }
      cursorPos=this.skipMaskCharacters(keycode, cursorPos);
      if(cursorPos===false){
          return false;
      }
      if(this.injectValue(keycode, cursorPos)){
          this.moveCursorToPosition(keycode, cursorPos);
      }
      return(false);
    },

    processMaskFocus : function()
	{
        if(this.field.getValue().length == 0)
		{
            var cursorPos = this.getCursorPosition();
            this.inputTextElement.value = this.viewMask;
            this.moveCursorToPosition(null, cursorPos);
        }
    },

    isManagedByBrowser : function(keyEvent, keycode, type){
        if(((type=='keypress' && keyEvent.charCode===0) ||
            type=='keydown') && (keycode.unicode==Ext.EventObject.TAB ||
            keycode.unicode==Ext.EventObject.RETURN ||
            keycode.unicode==Ext.EventObject.ENTER ||
            keycode.unicode==Ext.EventObject.SHIFT ||
            keycode.unicode==Ext.EventObject.CONTROL ||
            keycode.unicode==Ext.EventObject.ESC ||
            keycode.unicode==Ext.EventObject.PAGEUP ||
            keycode.unicode==Ext.EventObject.PAGEDOWN ||
            keycode.unicode==Ext.EventObject.END ||
            keycode.unicode==Ext.EventObject.HOME ||
            keycode.unicode==Ext.EventObject.LEFT ||
            keycode.unicode==Ext.EventObject.UP ||
            keycode.unicode==Ext.EventObject.RIGHT ||
            keycode.unicode==Ext.EventObject.DOWN)){
                return(true);
        }
        return(false);
    },

    handleEventBubble : function(keyEvent, keycode, type) {
        try {
            if(keycode && this.isManagedByBrowser(keyEvent, keycode, type)){
                return true;
            }
            keyEvent.stopEvent();
            return false;
        } catch(e) {
            alert(e.message);
        }
    },

    getCursorPosition : function() {
        var s, e, r;
        if(this.inputTextElement.createTextRange){
            r = document.selection.createRange().duplicate();
            r.moveEnd('character', this.inputTextElement.value.length);
            if(r.text === ''){
                s = this.inputTextElement.value.length;
            } else {
                s = this.inputTextElement.value.lastIndexOf(r.text);
            }
            r = document.selection.createRange().duplicate();
            r.moveStart('character', -this.inputTextElement.value.length);
            e = r.text.length;
        } else {
            s = this.inputTextElement.selectionStart;
            e = this.inputTextElement.selectionEnd;
        }
        return this.CursorPosition(s, e, r, this.inputTextElement.value);
    },

    moveCursorToPosition : function(keycode, cursorPosition) {
        var p = (!keycode || (keycode && keycode.isBackspace ))? cursorPosition.start: cursorPosition.start + 1;
        if(this.inputTextElement.createTextRange){
            cursorPosition.range.move('character', p);
            cursorPosition.range.select();
        } else {
            this.inputTextElement.selectionStart = p;
            this.inputTextElement.selectionEnd = p;
        }
    },

    injectValue : function(keycode, cursorPosition) {
        if (!keycode.isDelete && keycode.unicode == cursorPosition.previousValue.charCodeAt(cursorPosition.start))
            return true;
        var key;
        if(!keycode.isDelete && !keycode.isBackspace){
            key=this.getValidatedKey(keycode, cursorPosition);
        } else {
            if(cursorPosition.start == cursorPosition.end){
                key='_';
                if(keycode.isBackspace){
                    cursorPosition.dec();
                }
            } else {
                key=this.viewMask.substring(cursorPosition.start,cursorPosition.end);
            }
        }
        if(key){
            this.inputTextElement.value = cursorPosition.previousValue.substring(0,cursorPosition.start)
                + key +
                cursorPosition.previousValue.substring(cursorPosition.start + key.length,cursorPosition.previousValue.length);
            return true;
        }
        return false;
    },

    getKeyCode : function(onKeyDownEvent, type) {
        var keycode = {};
        keycode.unicode = onKeyDownEvent.getKey();
        keycode.isShiftPressed = onKeyDownEvent.shiftKey;
        
        keycode.isDelete = ((onKeyDownEvent.getKey() == Ext.EventObject.DELETE && type=='keydown') || ( type=='keypress' && onKeyDownEvent.charCode===0 && onKeyDownEvent.keyCode == Ext.EventObject.DELETE))? true: false;
        keycode.isTab = (onKeyDownEvent.getKey() == Ext.EventObject.TAB)? true: false;
        keycode.isBackspace = (onKeyDownEvent.getKey() == Ext.EventObject.BACKSPACE)? true: false;
        keycode.isLeftOrRightArrow = (onKeyDownEvent.getKey() == Ext.EventObject.LEFT || onKeyDownEvent.getKey() == Ext.EventObject.RIGHT)? true: false;
        keycode.pressedKey = String.fromCharCode(keycode.unicode);
        return(keycode);
    },

    CursorPosition : function(start, end, range, previousValue) {
        var cursorPosition = {};
        cursorPosition.start = isNaN(start)? 0: start;
        cursorPosition.end = isNaN(end)? 0: end;
        cursorPosition.range = range;
        cursorPosition.previousValue = previousValue;
        cursorPosition.inc = function(){cursorPosition.start++;cursorPosition.end++;};
        cursorPosition.dec = function(){cursorPosition.start--;cursorPosition.end--;};
        return(cursorPosition);
    }
};

Ext.applyIf(RegExp, {
  escape : function(str) {
    return new String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
  }
});

Ext.ux.InputTextMask=Ext.ux.netbox.InputTextMask;
Ext.preg('inputmask',Ext.ux.InputTextMask);







Ext.ux.form.ItemSelector = Ext.extend(Ext.form.Field,  {
    hideNavIcons:false,
    iconUp:"ico-up",
    iconDown:"ico-down",
    iconLeft:"ico-left",
    iconRight:"ico-right",
    iconTop:"ico-top",
    iconBottom:"ico-bottom",
    drawUpIcon:true,
    drawDownIcon:true,
    drawLeftIcon:true,
    drawRightIcon:true,
    drawTopIcon:true,
    drawBotIcon:true,
    delimiter:',',
    bodyStyle:null,
    border:false,
	
    defaultAutoCreate:{tag: "div"},
    
    multiselects:null,
	
	//by bt
	allowBlank	: true,
	blankText	: '� obrigat�rio selecionar ao menos um item',

    initComponent: function()
	{
		if(this.verticalSort === false)
		{
			this.drawUpIcon 	= false;
		    this.drawDownIcon	= false;
		    this.drawTopIcon	= false;
		    this.drawBotIcon	= false;
		}
		
		
        Ext.ux.form.ItemSelector.superclass.initComponent.call(this);
        this.addEvents({
            'rowdblclick' : true,
            'change' : true
        });
    }
	
	,onResize: function(w,h)
	{
		Ext.ux.form.ItemSelector.superclass.onResize.apply(this, arguments);
		
		
		this.pContainer.setWidth(w);
	}

    ,onRender: function(ct, position){
        Ext.ux.form.ItemSelector.superclass.onRender.call(this, ct, position);

        // Internal default configuration for both multiselects
        var msConfig = [{
            legend: 'Dispon&#237;vel',
            draggable: true,
            droppable: true
			,flex:1
        },{
            legend: 'Selecionado',
            droppable: true,
            draggable: true
			,flex:1
        }];
		
		//Configuracoes autom�ticas {
		
			this.multiselects[0] = this.multiselects[0]||{}; 
			this.multiselects[1] = this.multiselects[1]||{};
			
			this.multiselects[1].displayField 	= this.multiselects[1].displayField	|| this.multiselects[0].displayField;
			this.multiselects[1].valueField 	= this.multiselects[1].valueField	|| this.multiselects[0].valueField;
			
			if(!this.multiselects[1].store)
			{
				this.multiselects[1].store = new Ext.data.ArrayStore({
					 data	: []
					,fields	: [
					 	 this.multiselects[1].valueField
						,this.multiselects[1].displayField
					]
                });	
			}
			
		//}
	
        this.fromMultiselect = new Ext.ux.form.MultiSelect(Ext.applyIf(this.multiselects[0], msConfig[0]));
        this.fromMultiselect.on('dblclick', this.onRowDblClick, this);

        this.toMultiselect = new Ext.ux.form.MultiSelect(Ext.applyIf(this.multiselects[1], msConfig[1]));
        this.toMultiselect.on('dblclick', this.onRowDblClick, this);
		
 		var icons = new Ext.Panel({header:false, width:30,style:'text-align:center;'});
 
        this.pContainer = p = new Ext.Panel({
             bodyStyle		: this.bodyStyle
            ,border			: this.border
			,height			: Math.max(this.fromMultiselect.height,this.toMultiselect.height)||200
			,width			: this.el.getWidth()
			,layout			: {
				 type	: 'hbox'
				,align	: 'stretch'
			}
			,items:[this.fromMultiselect,icons,this.toMultiselect]
        });

       
        p.render(this.el);
  	    icons.el.down('.'+icons.bwrapCls).remove();
	
        // ICON HELL!!!
        var el=icons.getEl();
        
		this.toTopIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls:this.iconTop, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        el.createChild({tag: 'br'});
		
        this.upIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls: this.iconUp, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        el.createChild({tag: 'br'});
        this.addIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls:this.iconRight, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        el.createChild({tag: 'br'});
        this.removeIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls:this.iconLeft, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        el.createChild({tag: 'br'});
        this.downIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls:this.iconDown, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        el.createChild({tag: 'br'});
        this.toBottomIcon = el.createChild({tag:'img', src:Ext.BLANK_IMAGE_URL, cls:this.iconBottom, width:16, height:16, style:{cursor:'pointer', margin:'2px'}});
        
		this.toTopIcon.on('click', this.toTop, this);
        this.upIcon.on('click', this.up, this);
        this.downIcon.on('click', this.down, this);
        this.toBottomIcon.on('click', this.toBottom, this);
        this.addIcon.on('click', this.fromTo, this);
        this.removeIcon.on('click', this.toFrom, this);
		
        if (!this.drawUpIcon || this.hideNavIcons) { this.upIcon.dom.style.display='none'; }
        if (!this.drawDownIcon || this.hideNavIcons) { this.downIcon.dom.style.display='none'; }
        if (!this.drawLeftIcon || this.hideNavIcons) { this.addIcon.dom.style.display='none'; }
        if (!this.drawRightIcon || this.hideNavIcons) { this.removeIcon.dom.style.display='none'; }
        if (!this.drawTopIcon || this.hideNavIcons) { this.toTopIcon.dom.style.display='none'; }
        if (!this.drawBotIcon || this.hideNavIcons) { this.toBottomIcon.dom.style.display='none'; }

        var tb = p.body.first();
        this.el.setWidth(p.body.first().getWidth());
        p.body.removeClass();

        this.hiddenName = this.name;
        var hiddenTag = {tag: "input", type: "hidden", value: "", name: this.name};
        this.hiddenField = this.el.createChild(hiddenTag);
    }
    
	,onDestroy: function()
	{
	 	Ext.ux.form.ItemSelector.superclass.onDestroy.apply(this, arguments);
		delete this.pContainer;
	}
	
    ,doLayout: function(){
        if(this.rendered){
			this.pContainer.doLayout();
        }
    },

    afterRender: function(){
        Ext.ux.form.ItemSelector.superclass.afterRender.call(this);

        this.toStore = this.toMultiselect.store;
        this.toStore.on('add', this.valueChanged, this);
        this.toStore.on('remove', this.valueChanged, this);
        this.toStore.on('load', this.valueChanged, this);
  //    this.valueChanged(this.toStore); by bt. N�o quero que valide logo ao renderizar, sen�o ele j� vai marcar vermelho
    },

    toTop : function() {
        var selectionsArray = this.toMultiselect.view.getSelectedIndexes();
        var records = [];
        if (selectionsArray.length > 0) {
            selectionsArray.sort();
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.toMultiselect.view.store.getAt(selectionsArray[i]);
                records.push(record);
            }
            selectionsArray = [];
            for (var i=records.length-1; i>-1; i--) {
                record = records[i];
                this.toMultiselect.view.store.remove(record);
                this.toMultiselect.view.store.insert(0, record);
                selectionsArray.push(((records.length - 1) - i));
            }
        }
        this.toMultiselect.view.refresh();
        this.toMultiselect.view.select(selectionsArray);
    },

    toBottom : function() {
        var selectionsArray = this.toMultiselect.view.getSelectedIndexes();
        var records = [];
        if (selectionsArray.length > 0) {
            selectionsArray.sort();
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.toMultiselect.view.store.getAt(selectionsArray[i]);
                records.push(record);
            }
            selectionsArray = [];
            for (var i=0; i<records.length; i++) {
                record = records[i];
                this.toMultiselect.view.store.remove(record);
                this.toMultiselect.view.store.add(record);
                selectionsArray.push((this.toMultiselect.view.store.getCount()) - (records.length - i));
            }
        }
        this.toMultiselect.view.refresh();
        this.toMultiselect.view.select(selectionsArray);
    },

    up : function() {
        var record = null;
        var selectionsArray = this.toMultiselect.view.getSelectedIndexes();
        selectionsArray.sort();
        var newSelectionsArray = [];
        if (selectionsArray.length > 0) {
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.toMultiselect.view.store.getAt(selectionsArray[i]);
                if ((selectionsArray[i] - 1) >= 0) {
                    this.toMultiselect.view.store.remove(record);
                    this.toMultiselect.view.store.insert(selectionsArray[i] - 1, record);
                    newSelectionsArray.push(selectionsArray[i] - 1);
                }
            }
            this.toMultiselect.view.refresh();
            this.toMultiselect.view.select(newSelectionsArray);
        }
    },

    down : function() {
        var record = null;
        var selectionsArray = this.toMultiselect.view.getSelectedIndexes();
        selectionsArray.sort();
        selectionsArray.reverse();
        var newSelectionsArray = [];
        if (selectionsArray.length > 0) {
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.toMultiselect.view.store.getAt(selectionsArray[i]);
                if ((selectionsArray[i] + 1) < this.toMultiselect.view.store.getCount()) {
                    this.toMultiselect.view.store.remove(record);
                    this.toMultiselect.view.store.insert(selectionsArray[i] + 1, record);
                    newSelectionsArray.push(selectionsArray[i] + 1);
                }
            }
            this.toMultiselect.view.refresh();
            this.toMultiselect.view.select(newSelectionsArray);
        }
    },

    fromTo : function() {
        var selectionsArray = this.fromMultiselect.view.getSelectedIndexes();
        var records = [];
        if (selectionsArray.length > 0) {
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.fromMultiselect.view.store.getAt(selectionsArray[i]);
                records.push(record);
            }
            if(!this.allowDup)selectionsArray = [];
            for (var i=0; i<records.length; i++) {
                record = records[i];
                if(this.allowDup){
                    var x=new Ext.data.Record();
                    record.id=x.id;
                    delete x;
                    this.toMultiselect.view.store.add(record);
                }else{
                    this.fromMultiselect.view.store.remove(record);
                    this.toMultiselect.view.store.add(record);
                    selectionsArray.push((this.toMultiselect.view.store.getCount() - 1));
                }
            }
        }
        this.toMultiselect.view.refresh();
        this.fromMultiselect.view.refresh();
        var si = this.toMultiselect.store.sortInfo;
        if(si){
            this.toMultiselect.store.sort(si.field, si.direction);
        }
        this.toMultiselect.view.select(selectionsArray);
    },

    toFrom : function() {
        var selectionsArray = this.toMultiselect.view.getSelectedIndexes();
        var records = [];
        if (selectionsArray.length > 0) {
            for (var i=0; i<selectionsArray.length; i++) {
                record = this.toMultiselect.view.store.getAt(selectionsArray[i]);
                records.push(record);
            }
            selectionsArray = [];
            for (var i=0; i<records.length; i++) {
                record = records[i];
                this.toMultiselect.view.store.remove(record);
                if(!this.allowDup){
                    this.fromMultiselect.view.store.add(record);
                    selectionsArray.push((this.fromMultiselect.view.store.getCount() - 1));
                }
            }
        }
        this.fromMultiselect.view.refresh();
        this.toMultiselect.view.refresh();
        var si = this.fromMultiselect.store.sortInfo;
        if (si){
            this.fromMultiselect.store.sort(si.field, si.direction);
        }
        this.fromMultiselect.view.select(selectionsArray);
    },

    valueChanged: function(store) 
	{
        var record = null;
        var values = [];
        for (var i=0; i<store.getCount(); i++) {
            record = store.getAt(i);
            values.push(record.get(this.toMultiselect.valueField));
        }
		
		
        this.hiddenField.dom.value = values.join(this.delimiter);
        this.fireEvent('change', this, this.getValue(), this.hiddenField.dom.value);
		
		if(store === this.toStore)
			this.validate();
    },

    getValue : function() 
	{
        return this.hiddenField.dom.value;
    },
	
	getRawValue : function() {
        return this.hiddenField.dom.value;
    },

    onRowDblClick : function(vw, index, node, e) {
        if (vw == this.toMultiselect.view){
            this.toFrom();
        } else if (vw == this.fromMultiselect.view) {
            this.fromTo();
        }
        return this.fireEvent('rowdblclick', vw, index, node, e);
    },

    reset: function(){
        range = this.toMultiselect.store.getRange();
        this.toMultiselect.store.removeAll();
        this.fromMultiselect.store.add(range);
        var si = this.fromMultiselect.store.sortInfo;
        if (si){
            this.fromMultiselect.store.sort(si.field, si.direction);
        }
        this.valueChanged(this.toMultiselect.store);
    }

	,validateValue : function(value)
	{
		var v = (value||"").trim();
		
        if (v.length < 1) 
		{ 
             if (this.allowBlank) 
			 {
                 this.toMultiselect.clearInvalid();
                 return true;
             } 
			 else 
			 {
                 this.toMultiselect.markInvalid(this.blankText);
                 return false;
             }
        }
        return true;
    }
	
	,clearInvalid: function()
	{
		//super
		Ext.ux.form.ItemSelector.superclass.clearInvalid.apply(this,arguments);
		this.toMultiselect.clearInvalid();
	}
	
});

Ext.reg('itemselector', Ext.ux.form.ItemSelector);

//backwards compat
Ext.ux.ItemSelector = Ext.ux.form.ItemSelector;


//bruno -> adicionei bbar

Ext.ns('Ext.ux.form');


Ext.ux.form.MultiSelect = Ext.extend(Ext.form.Field,  {
    
    
    
    
    
    ddReorder:false,
    
    
    appendOnly:false,
    
    width:undefined,
    
    height:undefined,
    
    displayField:0,
    
    valueField:1,
    
    allowBlank:true,
    
    minSelections:0,
    
    maxSelections:Number.MAX_VALUE,
    
    blankText:Ext.form.TextField.prototype.blankText,
    
    minSelectionsText:'Minimum {0} item(s) required',
    
    maxSelectionsText:'Maximum {0} item(s) allowed',
    
    delimiter:',',
    

	cls:'ux-mselect',

    // private
    defaultAutoCreate : {tag: "div"},
	
	

    // private
    initComponent: function(){
        Ext.ux.form.MultiSelect.superclass.initComponent.call(this);
		
		if(!this.store)
			this.store = [];
			
        if(Ext.isArray(this.store)){
            if (Ext.isArray(this.store[0])){
                this.store = new Ext.data.ArrayStore({
                    fields: ['value','text'],
                    data: this.store
                });
                this.valueField = 'value';
            }else{
                this.store = new Ext.data.ArrayStore({
                    fields: ['text'],
                    data: this.store,
                    expandData: true
                });
                this.valueField = 'text';
            }
            this.displayField = 'text';
        } else {
            this.store = Ext.StoreMgr.lookup(this.store);
        }

        this.addEvents({
            'dblclick' : true,
            'click' : true,
            'change' : true,
            'drop' : true
        });
    },
	
	onResize: function(w,h)
	{
		Ext.ux.form.MultiSelect.superclass.onResize.apply(this, arguments);
		this.fs.setSize(w,h);
	},
	
    // private
    onRender: function(ct, position){
        Ext.ux.form.MultiSelect.superclass.onRender.call(this, ct, position);
		
		//by bruno  {
		
			var paging;
			if( this.enablePaging )
			{
				var pagingConfig = {
					 store		: this.store
					,pageSize	: 30
					,style		: 'border-bottom:none;'
				}		
				
				if(Ext.isObject(this.enablePaging))
					Ext.apply(pagingConfig,this.enablePaging);
					
				paging = new Ext.PagingToolbar(pagingConfig);
			}
		
		//}
		
        var fs = this.fs = new Ext.form.FieldSet({
            renderTo: this.el,
            title: this.legend,
            height: this.height,
            width: this.width,
            tbar: this.tbar,
			style: "padding:0; margin:0;",
            bodyStyle: 'overflow: auto; padding:0; margin:0;',
			bbar: paging
        });
		
		fs.el.child('legend').applyStyles("padding:0; margin:0 0 0 10px;");
		
        this.view = new Ext.ListView({
            multiSelect: true,
            store: this.store,
            columns: [{ header: 'Value', width: 1, dataIndex: this.displayField }],
            hideHeaders: true
        });

        fs.add(this.view);
		
        this.view.on('click', this.onViewClick, this);
        this.view.on('beforeclick', this.onViewBeforeClick, this);
        this.view.on('dblclick', this.onViewDblClick, this);

        this.hiddenName = this.name || Ext.id();
        var hiddenTag = { tag: "input", type: "hidden", value: "", name: this.hiddenName };
        this.hiddenField = this.el.createChild(hiddenTag);
        this.hiddenField.dom.disabled = this.hiddenName != this.name;
        fs.doLayout();
    },
	
	doLayout: function()
	{
		if(this.fs && Ext.isObject(this.fs.layout))
			this.fs.doLayout();
	},
	
    // private
    afterRender: function(){
        Ext.ux.form.MultiSelect.superclass.afterRender.call(this);

        if (this.ddReorder && !this.dragGroup && !this.dropGroup){
            this.dragGroup = this.dropGroup = 'MultiselectDD-' + Ext.id();
        }

        if (this.draggable || this.dragGroup){
            this.dragZone = new Ext.ux.form.MultiSelect.DragZone(this, {
                ddGroup: this.dragGroup
            });
        }
        if (this.droppable || this.dropGroup){
            this.dropZone = new Ext.ux.form.MultiSelect.DropZone(this, {
                ddGroup: this.dropGroup
            });
        }
    },

    // private
    onViewClick: function(vw, index, node, e) {
        this.fireEvent('change', this, this.getValue(), this.hiddenField.dom.value);
        this.hiddenField.dom.value = this.getValue();
        this.fireEvent('click', this, e);
        this.validate();
    },

    // private
    onViewBeforeClick: function(vw, index, node, e) {
        if (this.disabled) {return false;}
    },

    // private
    onViewDblClick : function(vw, index, node, e) {
        return this.fireEvent('dblclick', vw, index, node, e);
    },

    
    getValue: function(valueField){
        var returnArray = [];
        var selectionsArray = this.view.getSelectedIndexes();
        if (selectionsArray.length == 0) {return '';}
        for (var i=0; i<selectionsArray.length; i++) {
            returnArray.push(this.store.getAt(selectionsArray[i]).get((valueField != null) ? valueField : this.valueField));
        }
        return returnArray.join(this.delimiter);
    },

    
    setValue: function(values) {
        var index;
        var selections = [];
        this.view.clearSelections();
        this.hiddenField.dom.value = '';

        if (!values || (values == '')) { return; }

        if (!Ext.isArray(values)) { values = values.split(this.delimiter); }
        for (var i=0; i<values.length; i++) {
            index = this.view.store.indexOf(this.view.store.query(this.valueField,
                new RegExp('^' + values[i] + '$', "i")).itemAt(0));
            selections.push(index);
        }
        this.view.select(selections);
        this.hiddenField.dom.value = this.getValue();
		this.validate();
    },

    // inherit docs
    reset : function() {
        this.setValue('');
    },

    // inherit docs
    getRawValue: function(valueField) {
        var tmp = this.getValue(valueField);
        if (tmp.length) {
            tmp = tmp.split(this.delimiter);
        }
        else {
            tmp = [];
        }
        return tmp;
    },

    // inherit docs
    setRawValue: function(values){
        setValue(values);
    },

    // inherit docs
    validateValue : function(value){
        if (value.length < 1) { // if it has no value
             if (this.allowBlank) {
                 this.clearInvalid();
                 return true;
             } else {
                 this.markInvalid(this.blankText);
                 return false;
             }
        }
        if (value.length < this.minSelections) {
            this.markInvalid(String.format(this.minSelectionsText, this.minSelections));
            return false;
        }
        if (value.length > this.maxSelections) {
            this.markInvalid(String.format(this.maxSelectionsText, this.maxSelections));
            return false;
        }
        return true;
    },

    // inherit docs
    disable: function(){
        this.disabled = true;
        this.hiddenField.dom.disabled = true;
        this.fs.disable();
    },

    // inherit docs
    enable: function(){
        this.disabled = false;
        this.hiddenField.dom.disabled = false;
        this.fs.enable();
    },

    // inherit docs
    destroy: function(){
        Ext.destroy(this.fs, this.dragZone, this.dropZone);
        Ext.ux.form.MultiSelect.superclass.destroy.call(this);
    }
});


Ext.reg('multiselect', Ext.ux.form.MultiSelect);

//backwards compat
Ext.ux.Multiselect = Ext.ux.form.MultiSelect;


Ext.ux.form.MultiSelect.DragZone = function(ms, config){
    this.ms = ms;
    this.view = ms.view;
    var ddGroup = config.ddGroup || 'MultiselectDD';
    var dd;
    if (Ext.isArray(ddGroup)){
        dd = ddGroup.shift();
    } else {
        dd = ddGroup;
        ddGroup = null;
    }
    Ext.ux.form.MultiSelect.DragZone.superclass.constructor.call(this, this.ms.fs.body, { containerScroll: true, ddGroup: dd });
    this.setDraggable(ddGroup);
};

Ext.extend(Ext.ux.form.MultiSelect.DragZone, Ext.dd.DragZone, {
    onInitDrag : function(x, y){
        var el = Ext.get(this.dragData.ddel.cloneNode(true));
        this.proxy.update(el.dom);
        el.setWidth(el.child('em').getWidth());
        this.onStartDrag(x, y);
        return true;
    },
    
    // private
    collectSelection: function(data) {
        data.repairXY = Ext.fly(this.view.getSelectedNodes()[0]).getXY();
        var i = 0;
        this.view.store.each(function(rec){
            if (this.view.isSelected(i)) {
                var n = this.view.getNode(i);
                var dragNode = n.cloneNode(true);
                dragNode.id = Ext.id();
                data.ddel.appendChild(dragNode);
                data.records.push(this.view.store.getAt(i));
                data.viewNodes.push(n);
            }
            i++;
        }, this);
    },

    // override
    onEndDrag: function(data, e) {
        var d = Ext.get(this.dragData.ddel);
        if (d && d.hasClass("multi-proxy")) {
            d.remove();
        }
    },

    // override
    getDragData: function(e){
        var target = this.view.findItemFromChild(e.getTarget());
        if(target) {
            if (!this.view.isSelected(target) && !e.ctrlKey && !e.shiftKey) {
                this.view.select(target);
                this.ms.setValue(this.ms.getValue());
            }
            if (this.view.getSelectionCount() == 0 || e.ctrlKey || e.shiftKey) return false;
            var dragData = {
                sourceView: this.view,
                viewNodes: [],
                records: []
            };
            if (this.view.getSelectionCount() == 1) {
                var i = this.view.getSelectedIndexes()[0];
                var n = this.view.getNode(i);
                dragData.viewNodes.push(dragData.ddel = n);
                dragData.records.push(this.view.store.getAt(i));
                dragData.repairXY = Ext.fly(n).getXY();
            } else {
                dragData.ddel = document.createElement('div');
                dragData.ddel.className = 'multi-proxy';
                this.collectSelection(dragData);
            }
            return dragData;
        }
        return false;
    },

    // override the default repairXY.
    getRepairXY : function(e){
        return this.dragData.repairXY;
    },

    // private
    setDraggable: function(ddGroup){
        if (!ddGroup) return;
        if (Ext.isArray(ddGroup)) {
            Ext.each(ddGroup, this.setDraggable, this);
            return;
        }
        this.addToGroup(ddGroup);
    }
});

Ext.ux.form.MultiSelect.DropZone = function(ms, config){
    this.ms = ms;
    this.view = ms.view;
    var ddGroup = config.ddGroup || 'MultiselectDD';
    var dd;
    if (Ext.isArray(ddGroup)){
        dd = ddGroup.shift();
    } else {
        dd = ddGroup;
        ddGroup = null;
    }
    Ext.ux.form.MultiSelect.DropZone.superclass.constructor.call(this, this.ms.fs.body, { containerScroll: true, ddGroup: dd });
    this.setDroppable(ddGroup);
};

Ext.extend(Ext.ux.form.MultiSelect.DropZone, Ext.dd.DropZone, {
    
    getTargetFromEvent : function(e) {
        var target = e.getTarget();
        return target;
    },

    // private
    getDropPoint : function(e, n, dd){
        if (n == this.ms.fs.body.dom) { return "below"; }
        var t = Ext.lib.Dom.getY(n), b = t + n.offsetHeight;
        var c = t + (b - t) / 2;
        var y = Ext.lib.Event.getPageY(e);
        if(y <= c) {
            return "above";
        }else{
            return "below";
        }
    },

    // private
    isValidDropPoint: function(pt, n, data) {
        if (!data.viewNodes || (data.viewNodes.length != 1)) {
            return true;
        }
        var d = data.viewNodes[0];
        if (d == n) {
            return false;
        }
        if ((pt == "below") && (n.nextSibling == d)) {
            return false;
        }
        if ((pt == "above") && (n.previousSibling == d)) {
            return false;
        }
        return true;
    },

    // override
    onNodeEnter : function(n, dd, e, data){
        return false;
    },

    // override
    onNodeOver : function(n, dd, e, data){
        var dragElClass = this.dropNotAllowed;
        var pt = this.getDropPoint(e, n, dd);
        if (this.isValidDropPoint(pt, n, data)) {
            if (this.ms.appendOnly) {
                return "x-tree-drop-ok-below";
            }

            // set the insert point style on the target node
            if (pt) {
                var targetElClass;
                if (pt == "above"){
                    dragElClass = n.previousSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-above";
                    targetElClass = "x-view-drag-insert-above";
                } else {
                    dragElClass = n.nextSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-below";
                    targetElClass = "x-view-drag-insert-below";
                }
                if (this.lastInsertClass != targetElClass){
                    Ext.fly(n).replaceClass(this.lastInsertClass, targetElClass);
                    this.lastInsertClass = targetElClass;
                }
            }
        }
        return dragElClass;
    },

    // private
    onNodeOut : function(n, dd, e, data){
        this.removeDropIndicators(n);
    },

    // private
    onNodeDrop : function(n, dd, e, data){
        if (this.ms.fireEvent("drop", this, n, dd, e, data) === false) {
            return false;
        }
        var pt = this.getDropPoint(e, n, dd);
        if (n != this.ms.fs.body.dom)
            n = this.view.findItemFromChild(n);
        var insertAt = (this.ms.appendOnly || (n == this.ms.fs.body.dom)) ? this.view.store.getCount() : this.view.indexOf(n);
        if (pt == "below") {
            insertAt++;
        }

        var dir = false;

        // Validate if dragging within the same MultiSelect
        if (data.sourceView == this.view) {
            // If the first element to be inserted below is the target node, remove it
            if (pt == "below") {
                if (data.viewNodes[0] == n) {
                    data.viewNodes.shift();
                }
            } else {  // If the last element to be inserted above is the target node, remove it
                if (data.viewNodes[data.viewNodes.length - 1] == n) {
                    data.viewNodes.pop();
                }
            }

            // Nothing to drop...
            if (!data.viewNodes.length) {
                return false;
            }

            // If we are moving DOWN, then because a store.remove() takes place first,
            // the insertAt must be decremented.
            if (insertAt > this.view.store.indexOf(data.records[0])) {
                dir = 'down';
                insertAt--;
            }
        }

        for (var i = 0; i < data.records.length; i++) {
            var r = data.records[i];
            if (data.sourceView) {
                data.sourceView.store.remove(r);
            }
            this.view.store.insert(dir == 'down' ? insertAt : insertAt++, r);
            var si = this.view.store.sortInfo;
            if(si){
                this.view.store.sort(si.field, si.direction);
            }
        }
        return true;
    },

    // private
    removeDropIndicators : function(n){
        if(n){
            Ext.fly(n).removeClass([
                "x-view-drag-insert-above",
                "x-view-drag-insert-left",
                "x-view-drag-insert-right",
                "x-view-drag-insert-below"]);
            this.lastInsertClass = "_noclass";
        }
    },

    // private
    setDroppable: function(ddGroup){
        if (!ddGroup) return;
        if (Ext.isArray(ddGroup)) {
            Ext.each(ddGroup, this.setDroppable, this);
            return;
        }
        this.addToGroup(ddGroup);
    }
});


Ext.ns('Ext.ux.grid');


Ext.ux.grid.RowExpander = Ext.extend(Ext.util.Observable, {
    
    expandOnEnter : true,
    
    expandOnDblClick : true,

    header : '',
    width : 20,
    sortable : false,
    fixed : true,
    menuDisabled : true,
    dataIndex : '',
    id : 'expander',
    lazyRender : true,
    enableCaching : true,

    constructor: function(config){
        Ext.apply(this, config);

        this.addEvents({
            
            beforeexpand: true,
            
            expand: true,
            
            beforecollapse: true,
            
            collapse: true
        });

        Ext.ux.grid.RowExpander.superclass.constructor.call(this);

        if(this.tpl){
            if(typeof this.tpl == 'string'){
                this.tpl = new Ext.Template(this.tpl);
            }
            this.tpl.compile();
        }

        this.state = {};
        this.bodyContent = {};
    },

    getRowClass : function(record, rowIndex, p, ds){
        p.cols = p.cols-1;
        var content = this.bodyContent[record.id];
        if(!content && !this.lazyRender){
            content = this.getBodyContent(record, rowIndex);
        }
        if(content){
            p.body = content;
        }
        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
    },

    init : function(grid){
        this.grid = grid;

        var view = grid.getView();
        view.getRowClass = this.getRowClass.createDelegate(this);

        view.enableRowBody = true;


        grid.on('render', this.onRender, this);
        grid.on('beforedestroy', this.onDestroy, this);
    },

    // @private
    onRender: function() {
        var grid = this.grid;
        var mainBody = grid.getView().mainBody;
        mainBody.on('mousedown', this.onMouseDown, this, {delegate: '.x-grid3-row-expander'});
        if (this.expandOnEnter) {
            this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), {
                'enter' : this.onEnter,
                scope: this
            });
        }
        if (this.expandOnDblClick) {
            grid.on('rowdblclick', this.onRowDblClick, this);
        }
    },
    
    // @private    
    onDestroy: function() {
        this.keyNav.disable();
        delete this.keyNav;
        var mainBody = this.grid.getView().mainBody;
        mainBody.un('mousedown', this.onMouseDown, this);
    },
    // @private
    onRowDblClick: function(grid, rowIdx, e) {
        this.toggleRow(rowIdx);
    },

    onEnter: function(e) {
        var g = this.grid;
        var sm = g.getSelectionModel();
        var sels = sm.getSelections();
        for (var i = 0, len = sels.length; i < len; i++) {
            var rowIdx = g.getStore().indexOf(sels[i]);
            this.toggleRow(rowIdx);
        }
    },

    getBodyContent : function(record, index){
        if(!this.enableCaching){
            return this.tpl.apply(record.data);
        }
        var content = this.bodyContent[record.id];
        if(!content){
            content = this.tpl.apply(record.data);
            this.bodyContent[record.id] = content;
        }
        return content;
    },

    onMouseDown : function(e, t){
        e.stopEvent();
        var row = e.getTarget('.x-grid3-row');
        this.toggleRow(row);
    },

    renderer : function(v, p, record){
        p.cellAttr = 'rowspan="2"';
        return '<div class="x-grid3-row-expander">&#160;</div>';
    },

    beforeExpand : function(record, body, rowIndex){
        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
            if(this.tpl && this.lazyRender){
                body.innerHTML = this.getBodyContent(record, rowIndex);
            }
            return true;
        }else{
            return false;
        }
    },

    toggleRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
    },

    expandRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
        if(this.beforeExpand(record, body, row.rowIndex)){
            this.state[record.id] = true;
            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
            this.fireEvent('expand', this, record, body, row.rowIndex);
        }
    },

    collapseRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
        if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){
            this.state[record.id] = false;
            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
            this.fireEvent('collapse', this, record, body, row.rowIndex);
        }
    }
});

Ext.preg('rowexpander', Ext.ux.grid.RowExpander);

//backwards compat
Ext.grid.RowExpander = Ext.ux.grid.RowExpander;

Ext.ns('Ext.ux.grid');


Ext.ux.grid.RowEditor = Ext.extend(Ext.Panel, {
    floating: {zindex:2},
    shadow: false,
    layout: 'hbox',
    cls: 'x-small-editor',
    buttonAlign: 'center',
    baseCls: 'x-row-editor',
    elements: 'header,footer,body',
    frameWidth: 5,
    buttonPad: 3,
    clicksToEdit: 'auto',
    monitorValid: true,
    focusDelay: 250,
    errorSummary: false,

    saveText: 'Save',
    cancelText: 'Cancel',
    commitChangesText: 'You need to commit or cancel your changes',
    errorText: 'Errors',

    defaults: {
        normalWidth: true
    },

    initComponent: function(){
        Ext.ux.grid.RowEditor.superclass.initComponent.call(this);
        this.addEvents(
            
            'beforeedit',
            
            'canceledit',
            
            'validateedit',
            
            'afteredit'
        );
    },

    init: function(grid){
        this.grid = grid;
        this.ownerCt = grid;
        if(this.clicksToEdit === 2){
            grid.on('rowdblclick', this.onRowDblClick, this);
        }else{
            grid.on('rowclick', this.onRowClick, this);
            if(Ext.isIE){
                grid.on('rowdblclick', this.onRowDblClick, this);
            }
        }

        // stopEditing without saving when a record is removed from Store.
        grid.getStore().on('remove', function() {
            this.stopEditing(false);
        },this);

        grid.on({
            scope: this,
            keydown: this.onGridKey,
            columnresize: this.verifyLayout,
            columnmove: this.refreshFields,
            reconfigure: this.refreshFields,
            beforedestroy : this.beforedestroy,
            destroy : this.destroy,
            bodyscroll: {
                buffer: 250,
                fn: this.positionButtons
            }
        });
        grid.getColumnModel().on('hiddenchange', this.verifyLayout, this, {delay:1});
        grid.getView().on('refresh', this.stopEditing.createDelegate(this, []));
    },

    beforedestroy: function() {
        this.grid.getStore().un('remove', this.onStoreRemove, this);
        this.stopEditing(false);
        Ext.destroy(this.btns);
    },

    refreshFields: function(){
        this.initFields();
        this.verifyLayout();
    },

    isDirty: function(){
        var dirty;
        this.items.each(function(f){
            if(String(this.values[f.id]) !== String(f.getValue())){
                dirty = true;
                return false;
            }
        }, this);
        return dirty;
    },

    startEditing: function(rowIndex, doFocus){
        if(this.editing && this.isDirty()){
            this.showTooltip(this.commitChangesText);
            return;
        }
        if(Ext.isObject(rowIndex)){
            rowIndex = this.grid.getStore().indexOf(rowIndex);
        }
        if(this.fireEvent('beforeedit', this, rowIndex) !== false){
            this.editing = true;
            var g = this.grid, view = g.getView(),
                row = view.getRow(rowIndex),
                record = g.store.getAt(rowIndex);

            this.record = record;
            this.rowIndex = rowIndex;
            this.values = {};
            if(!this.rendered){
                this.render(view.getEditorParent());
            }
            var w = Ext.fly(row).getWidth();
            this.setSize(w);
            if(!this.initialized){
                this.initFields();
            }
            var cm = g.getColumnModel(), fields = this.items.items, f, val;
            for(var i = 0, len = cm.getColumnCount(); i < len; i++){
                val = this.preEditValue(record, cm.getDataIndex(i));
                f = fields[i];
                f.setValue(val);
                this.values[f.id] = Ext.isEmpty(val) ? '' : val;
            }
            this.verifyLayout(true);
            if(!this.isVisible()){
                this.setPagePosition(Ext.fly(row).getXY());
            } else{
                this.el.setXY(Ext.fly(row).getXY(), {duration:0.15});
            }
            if(!this.isVisible()){
                this.show().doLayout();
            }
            if(doFocus !== false){
                this.doFocus.defer(this.focusDelay, this);
            }
        }
    },

    stopEditing : function(saveChanges){
        this.editing = false;
        if(!this.isVisible()){
            return;
        }
        if(saveChanges === false || !this.isValid()){
            this.hide();
            this.fireEvent('canceledit', this, saveChanges === false);
            return;
        }
        var changes = {},
            r = this.record,
            hasChange = false,
            cm = this.grid.colModel,
            fields = this.items.items;
        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
            if(!cm.isHidden(i)){
                var dindex = cm.getDataIndex(i);
                if(!Ext.isEmpty(dindex)){
                    var oldValue = r.data[dindex],
                        value = this.postEditValue(fields[i].getValue(), oldValue, r, dindex);
                    if(String(oldValue) !== String(value)){
                        changes[dindex] = value;
                        hasChange = true;
                    }
                }
            }
        }
        if(hasChange && this.fireEvent('validateedit', this, changes, r, this.rowIndex) !== false){
            r.beginEdit();
            Ext.iterate(changes, function(name, value){
                r.set(name, value);
            });
            r.endEdit();
            this.fireEvent('afteredit', this, changes, r, this.rowIndex);
        }
        this.hide();
    },

    verifyLayout: function(force){
        if(this.el && (this.isVisible() || force === true)){
            var row = this.grid.getView().getRow(this.rowIndex);
            this.setSize(Ext.fly(row).getWidth(), Ext.isIE ? Ext.fly(row).getHeight() + 9 : undefined);
            var cm = this.grid.colModel, fields = this.items.items;
            for(var i = 0, len = cm.getColumnCount(); i < len; i++){
                if(!cm.isHidden(i)){
                    var adjust = 0;
                    if(i === (len - 1)){
                        adjust += 3; // outer padding
                    } else{
                        adjust += 1;
                    }
                    fields[i].show();
                    fields[i].setWidth(cm.getColumnWidth(i) - adjust);
                } else{
                    fields[i].hide();
                }
            }
            this.doLayout();
            this.positionButtons();
        }
    },

    slideHide : function(){
        this.hide();
    },

    initFields: function(){
        var cm = this.grid.getColumnModel(), pm = Ext.layout.ContainerLayout.prototype.parseMargins;
        this.removeAll(false);
        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
            var c = cm.getColumnAt(i),
                ed = c.getEditor();
            if(!ed){
                ed = c.displayEditor || new Ext.form.DisplayField();
            }else{
                ed = ed.field;
            }
            if(i == 0){
                ed.margins = pm('0 1 2 1');
            } else if(i == len - 1){
                ed.margins = pm('0 0 2 1');
            } else{
                ed.margins = pm('0 1 2');
            }
            ed.setWidth(cm.getColumnWidth(i));
            ed.column = c;
            if(ed.ownerCt !== this){
                ed.on('focus', this.ensureVisible, this);
                ed.on('specialkey', this.onKey, this);
            }
            this.insert(i, ed);
        }
        this.initialized = true;
    },

    onKey: function(f, e){
        if(e.getKey() === e.ENTER){
            this.stopEditing(true);
            e.stopPropagation();
        }
    },

    onGridKey: function(e){
        if(e.getKey() === e.ENTER && !this.isVisible()){
            var r = this.grid.getSelectionModel().getSelected();
            if(r){
                var index = this.grid.store.indexOf(r);
                this.startEditing(index);
                e.stopPropagation();
            }
        }
    },

    ensureVisible: function(editor){
        if(this.isVisible()){
             this.grid.getView().ensureVisible(this.rowIndex, this.grid.colModel.getIndexById(editor.column.id), true);
        }
    },

    onRowClick: function(g, rowIndex, e){
        if(this.clicksToEdit == 'auto'){
            var li = this.lastClickIndex;
            this.lastClickIndex = rowIndex;
            if(li != rowIndex && !this.isVisible()){
                return;
            }
        }
        this.startEditing(rowIndex, false);
        this.doFocus.defer(this.focusDelay, this, [e.getPoint()]);
    },

    onRowDblClick: function(g, rowIndex, e){
        this.startEditing(rowIndex, false);
        this.doFocus.defer(this.focusDelay, this, [e.getPoint()]);
    },

    onRender: function(){

        Ext.ux.grid.RowEditor.superclass.onRender.apply(this, arguments);
        this.el.swallowEvent(['keydown', 'keyup', 'keypress']);
        this.btns = new Ext.Panel({
            baseCls: 'x-plain',
            cls: 'x-btns',
            elements:'body',
            layout: 'table',
            width: (this.minButtonWidth * 2) + (this.frameWidth * 2) + (this.buttonPad * 4), // width must be specified for IE
            items: [{
                ref: 'saveBtn',
                itemId: 'saveBtn',
                xtype: 'button',
                text: this.saveText,
                width: this.minButtonWidth,
                handler: this.stopEditing.createDelegate(this, [true])
            }, {
                xtype: 'button',
                text: this.cancelText,
                width: this.minButtonWidth,
                handler: this.stopEditing.createDelegate(this, [false])
            }]
        });
        this.btns.render(this.bwrap);
    },

    afterRender: function(){
        Ext.ux.grid.RowEditor.superclass.afterRender.apply(this, arguments);
        this.positionButtons();
        if(this.monitorValid){
            this.startMonitoring();
        }
    },

    onShow: function(){
        if(this.monitorValid){
            this.startMonitoring();
        }
        Ext.ux.grid.RowEditor.superclass.onShow.apply(this, arguments);
    },

    onHide: function(){
        Ext.ux.grid.RowEditor.superclass.onHide.apply(this, arguments);
        this.stopMonitoring();
        this.grid.getView().focusRow(this.rowIndex);
    },

    positionButtons: function(){
        if(this.btns){
            var g = this.grid,
                h = this.el.dom.clientHeight,
                view = g.getView(),
                scroll = view.scroller.dom.scrollLeft,
                bw = this.btns.getWidth(),
                width = Math.min(g.getWidth(), g.getColumnModel().getTotalWidth());

            this.btns.el.shift({left: (width/2)-(bw/2)+scroll, top: h - 2, stopFx: true, duration:0.2});
        }
    },

    // private
    preEditValue : function(r, field){
        var value = r.data[field];
        return this.autoEncode && typeof value === 'string' ? Ext.util.Format.htmlDecode(value) : value;
    },

    // private
    postEditValue : function(value, originalValue, r, field){
        return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
    },

    doFocus: function(pt){
        if(this.isVisible()){
            var index = 0,
                cm = this.grid.getColumnModel(),
                c,
                ed;
            if(pt){
                index = this.getTargetColumnIndex(pt);
            }
            for(var i = index||0, len = cm.getColumnCount(); i < len; i++){
                c = cm.getColumnAt(i);
                ed = c.getEditor();
                if(!c.hidden && ed){
                    ed.field.focus();
                    break;
                }
            }
        }
    },

    getTargetColumnIndex: function(pt){
        var grid = this.grid,
            v = grid.view,
            x = pt.left,
            cms = grid.colModel.config,
            i = 0,
            match = false;
        for(var len = cms.length, c; c = cms[i]; i++){
            if(!c.hidden){
                if(Ext.fly(v.getHeaderCell(i)).getRegion().right >= x){
                    match = i;
                    break;
                }
            }
        }
        return match;
    },

    startMonitoring : function(){
        if(!this.bound && this.monitorValid){
            this.bound = true;
            Ext.TaskMgr.start({
                run : this.bindHandler,
                interval : this.monitorPoll || 200,
                scope: this
            });
        }
    },

    stopMonitoring : function(){
        this.bound = false;
        if(this.tooltip){
            this.tooltip.hide();
        }
    },

    isValid: function(){
        var valid = true;
        this.items.each(function(f){
            if(!f.isValid(true)){
                valid = false;
                return false;
            }
        });
        return valid;
    },

    // private
    bindHandler : function(){
        if(!this.bound){
            return false; // stops binding
        }
        var valid = this.isValid();
        if(!valid && this.errorSummary){
            this.showTooltip(this.getErrorText().join(''));
        }
        this.btns.saveBtn.setDisabled(!valid);
        this.fireEvent('validation', this, valid);
    },

    showTooltip: function(msg){
        var t = this.tooltip;
        if(!t){
            t = this.tooltip = new Ext.ToolTip({
                maxWidth: 600,
                cls: 'errorTip',
                width: 300,
                title: this.errorText,
                autoHide: false,
                anchor: 'left',
                anchorToTarget: true,
                mouseOffset: [40,0]
            });
        }
        var v = this.grid.getView(),
            top = parseInt(this.el.dom.style.top, 10),
            scroll = v.scroller.dom.scrollTop,
            h = this.el.getHeight();

        if(top + h >= scroll){
            t.initTarget(this.items.last().getEl());
            if(!t.rendered){
                t.show();
                t.hide();
            }
            t.body.update(msg);
            t.doAutoWidth(20);
            t.show();
        }else if(t.rendered){
            t.hide();
        }
    },

    getErrorText: function(){
        var data = ['<ul>'];
        this.items.each(function(f){
            if(!f.isValid(true)){
                data.push('<li>', f.getActiveError(), '</li>');
            }
        });
        data.push('</ul>');
        return data;
    }
});
Ext.preg('roweditor', Ext.ux.grid.RowEditor);

// vim: ts=4:sw=4:nu:fdc=4:nospell




Ext.ns('Ext.ux.grid');


Ext.ux.grid.Search = function(config) {
	Ext.apply(this, config);
	Ext.ux.grid.Search.superclass.constructor.call(this);
}; // eo constructor

Ext.extend(Ext.ux.grid.Search, Ext.util.Observable, {
	

	
	 searchText:'Filtro'

	 
	,searchTipText:'Digite um texto para filtrar e pressione Enter'

	
	,selectAllText:'Selecionar tudo'

	
	,position:'bottom'

	
	,iconCls:'ico-lupa'

	
	,checkIndexes:'all'

	
	,disableIndexes:[]

	
	,dateFormat:undefined

	
	,showSelectAll:true

	
	,menuStyle:'checkbox'

	

	
	,minCharsTipText:'Tamanho m&#237;nimo: {0}'

	
	,mode:'local'

	

	
	,width:200

	
	,xtype:'gridsearch'

	
	,paramNames: {
		 fields:'fields'
		,query:'query'
	}

	
	,shortcutKey:'r'

	
	,shortcutModifier:'alt'

	

	

	
	
	// {{{
	
	,init:function(grid) {
		this.grid = grid;

		// setup toolbar container if id was given
		if('string' === typeof this.toolbarContainer) {
			this.toolbarContainer = Ext.getCmp(this.toolbarContainer);
		}

		// do our processing after grid render and reconfigure
		grid.onRender = grid.onRender.createSequence(this.onRender, this);
		grid.reconfigure = grid.reconfigure.createSequence(this.reconfigure, this);
	} // eo function init
	// }}}
	// {{{
	
	,onRender:function() {
		var panel = this.toolbarContainer || this.grid;
		var tb = 'bottom' === this.position ? panel.bottomToolbar : panel.topToolbar;

		// add menu
		this.menu = new Ext.menu.Menu();

		// handle position
		if('right' === this.align) {
			tb.addFill();
		}
		else {
			if(0 < tb.items.getCount()) {
				tb.addSeparator();
			}
		}

		// add menu button
		tb.add({
			 text:this.searchText
			,menu:this.menu
			,iconCls:this.iconCls
		});

		// add input field (TwinTriggerField in fact)
		this.field = new Ext.form.TwinTriggerField({
			 width:this.width
			,selectOnFocus:undefined === this.selectOnFocus ? true : this.selectOnFocus
			,trigger1Class:'x-form-clear-trigger'
			,trigger2Class:this.minChars ? 'x-hidden' : 'x-form-search-trigger'
			,onTrigger1Click:this.minChars ? Ext.emptyFn : this.onTriggerClear.createDelegate(this)
			,onTrigger2Click:this.onTriggerSearch.createDelegate(this)
			,minLength:this.minLength
		});

		// install event handlers on input field
		this.field.on('render', function() {
			this.field.el.dom.qtip = this.minChars ? String.format(this.minCharsTipText, this.minChars) : this.searchTipText;

			if(this.minChars) {
				this.field.el.on({scope:this, buffer:300, keyup:this.onKeyUp});
			}

			// install key map
			var map = new Ext.KeyMap(this.field.el, [{
				 key:Ext.EventObject.ENTER
				,scope:this
				,fn:this.onTriggerSearch
			},{
				 key:Ext.EventObject.ESC
				,scope:this
				,fn:this.onTriggerClear
			}]);
			map.stopEvent = true;
		}, this, {single:true});

		tb.add(this.field);

		// reconfigure
		this.reconfigure();

		// keyMap
		if(this.shortcutKey && this.shortcutModifier) {
			var shortcutEl = this.grid.getEl();
			var shortcutCfg = [{
				 key:this.shortcutKey
				,scope:this
				,stopEvent:true
				,fn:function() {
					this.field.focus();
				}
			}];
			shortcutCfg[0][this.shortcutModifier] = true;
			this.keymap = new Ext.KeyMap(shortcutEl, shortcutCfg);
		}

		if(true === this.autoFocus) {
			this.grid.store.on({scope:this, load:function(){this.field.focus();}});
		}
	} // eo function onRender
	// }}}
	// {{{
	
	,onKeyUp:function() {
		var length = this.field.getValue().toString().length;
		if(0 === length || this.minChars <= length) {
			this.onTriggerSearch();
		}
	} // eo function onKeyUp
	// }}}
	// {{{
	
	,onTriggerClear:function() {
		if(this.field.getValue()) {
			this.field.setValue('');
			this.field.focus();
			this.onTriggerSearch();
		}
	} // eo function onTriggerClear
	// }}}
	// {{{
	
	,onTriggerSearch:function() 
	{
        if(!this.field.isValid()) {
            return;
        }
        var val = this.field.getValue();
        var store = this.grid.store;
		var re = new RegExp(val, 'gi');

        // grid's store filter
        if('local' === this.mode) 
		{
            store.clearFilter();
			
            if(val) 
			{
                store.filterBy(function(r,rowIndex)
				{			
					var retorno = false;
                    
					this.menu.items.each(function(item) 
					{
                        if(!item.checked || !item.dataIndex)
                            return;
							
						if(retorno)
							return false; 	
						
                        var valor = r.get(item.dataIndex);
						
						if(item.renderer) 
							valor = item.renderer.call( this , valor, store.reader.meta , r , rowIndex , 0 , store );
										
						if(Ext.isDate(valor)) 
                        	valor = valor.format(this.dateFormat || r.fields.get(item.dataIndex).dateFormat);
                      
                        retorno = re.test(valor);
						
                    }, this);
                    
                    return retorno;
					
                }, this);
            }
            else {
            }
        }
        // ask server to filter records
        else {
            // clear start (necessary if we have paging)
            if(store.lastOptions && store.lastOptions.params) {
                store.lastOptions.params[store.paramNames.start] = 0;
            }

            // get fields to search array
            var fields = [];
            this.menu.items.each(function(item) {
                if(item.checked) {
                    fields.push(item.dataIndex);
                }
            });

            // add fields and query to baseParams of store
            delete(store.baseParams[this.paramNames.fields]);
            delete(store.baseParams[this.paramNames.query]);
            if (store.lastOptions && store.lastOptions.params) {
                delete(store.lastOptions.params[this.paramNames.fields]);
                delete(store.lastOptions.params[this.paramNames.query]);
            }
            if(fields.length) {
                store.baseParams[this.paramNames.fields] = Ext.encode(fields);
                store.baseParams[this.paramNames.query] = val;
            }

            // reload store
            store.reload();
        }

    } // eo function onTriggerSearch
	// }}}
	// {{{
	
	,setDisabled:function() {
		this.field.setDisabled.apply(this.field, arguments);
	} // eo function setDisabled
	// }}}
	// {{{
	
	,enable:function() {
		this.setDisabled(false);
	} // eo function enable
	// }}}
	// {{{
	
	,disable:function() {
		this.setDisabled(true);
	} // eo function disable
	// }}}
	// {{{
	
	,reconfigure:function() {

		// {{{
		// remove old items
		var menu = this.menu;
		menu.removeAll();

		// add Select All item plus separator
		if(this.showSelectAll && 'radio' !== this.menuStyle) {
			menu.add(new Ext.menu.CheckItem({
				 text:this.selectAllText
				,checked:!(this.checkIndexes instanceof Array)
				,hideOnClick:false
				,handler:function(item) {
					var checked = ! item.checked;
					item.parentMenu.items.each(function(i) {
						if(item !== i && i.setChecked && !i.disabled) {
							i.setChecked(checked);
						}
					});
				}
			}),'-');
		}

		// }}}
		// {{{
		// add new items
		var cm = this.grid.colModel;
		var group = undefined;
		if('radio' === this.menuStyle) {
			group = 'g' + (new Date).getTime();	
		}
		Ext.each(cm.config, function(config) {
			var disable = false;
			if(config.header && config.dataIndex) {
				Ext.each(this.disableIndexes, function(item) {
					disable = disable ? disable : item === config.dataIndex;
				});
				if(!disable) {
					menu.add(new Ext.menu.CheckItem({
						 text:config.header
						,hideOnClick:false
						,group:group
						,checked:'all' === this.checkIndexes
						,dataIndex	: config.dataIndex
						,renderer	: config.renderer
					}));
				}
			}
		}, this);
		// }}}
		// {{{
		// check items
		if(this.checkIndexes instanceof Array) {
			Ext.each(this.checkIndexes, function(di) {
				var item = menu.items.find(function(itm) {
					return itm.dataIndex === di;
				});
				if(item) {
					item.setChecked(true, true);
				}
			}, this);
		}
		// }}}
		// {{{
		// disable items
		if(this.readonlyIndexes instanceof Array) {
			Ext.each(this.readonlyIndexes, function(di) {
				var item = menu.items.find(function(itm) {
					return itm.dataIndex === di;
				});
				if(item) {
					item.disable();
				}
			}, this);
		}
		// }}}

	} // eo function reconfigure
	// }}}

}); // eo extend

// eof



Ext.ns('Ext.ux.form');


Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
    
     dateValidator:null
    
    ,defaultAutoCreate:{tag:'input', type:'hidden'}
    
    ,dtSeparator:' '
    
    ,hiddenFormat:'Y-m-d H:i:s'
    
    ,otherToNow:true
    
    
    ,timePosition:'right' // valid values:'below', 'right'
    
    ,timeValidator:null
    
    ,timeWidth:100
    
    ,dateFormat:'d/m/Y'
    
    ,timeFormat:'H:i:s '
    
    
	
	,allowBlank: true

    // {{{
    
    ,initComponent:function() {
        // call parent initComponent
        Ext.ux.form.DateTime.superclass.initComponent.call(this);

        // create DateField
        var dateConfig = Ext.apply({}, {
             id:this.id + '-date'
            ,format:this.dateFormat || Ext.form.DateField.prototype.format
            ,width:this.timeWidth
            ,selectOnFocus:this.selectOnFocus
            ,validator:this.dateValidator
            ,listeners:{
                  blur:{scope:this, fn:this.onBlur}
                 ,focus:{scope:this, fn:this.onFocus}
            }
        }, this.dateConfig);
		
		if(this.allowBlank === false)
			dateConfig.allowBlank = false;
			
        this.df = new Ext.form.DateField(dateConfig);
        this.df.ownerCt = this;
        delete(this.dateFormat);

        // create TimeField
        var timeConfig = Ext.apply({}, {
             id:this.id + '-time'
            ,format:this.timeFormat || Ext.form.TimeField.prototype.format
            ,width:this.timeWidth
            ,selectOnFocus:this.selectOnFocus
            ,validator:this.timeValidator
            ,listeners:{
                  blur:{scope:this, fn:this.onBlur}
                 ,focus:{scope:this, fn:this.onFocus}
            }
        }, this.timeConfig);
		
		if(this.allowBlank === false)
			timeConfig.allowBlank = false;
		
        this.tf = new Ext.form.TimeField(timeConfig);
        this.tf.ownerCt = this;
        delete(this.timeFormat);

        // relay events
        this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
        this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);

    } // eo function initComponent
    // }}}
    // {{{
    
    ,onRender:function(ct, position) {
        // don't run more than once
        if(this.isRendered) {
            return;
        }

        // render underlying hidden field
        Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);

        // render DateField and TimeField
        // create bounding table
        var t;
        if('below' === this.timePosition || 'bellow' === this.timePosition) {
            t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
                 {tag:'tr',children:[{tag:'td', style:'padding-bottom:1px', cls:'ux-datetime-date'}]}
                ,{tag:'tr',children:[{tag:'td', cls:'ux-datetime-time'}]}
            ]}, true);
        }
        else {
            t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
                {tag:'tr',children:[
                    {tag:'td',style:'padding-right:4px', cls:'ux-datetime-date'},{tag:'td', cls:'ux-datetime-time'}
                ]}
            ]}, true);
        }

        this.tableEl = t;
        this.wrap = t.wrap({cls:'x-form-field-wrap'});
//        this.wrap = t.wrap();
        this.wrap.on("mousedown", this.onMouseDown, this, {delay:10});

        // render DateField & TimeField
        this.df.render(t.child('td.ux-datetime-date'));
        this.tf.render(t.child('td.ux-datetime-time'));

        // workaround for IE trigger misalignment bug
        // see http://extjs.com/forum/showthread.php?p=341075#post341075
//        if(Ext.isIE && Ext.isStrict) {
//            t.select('input').applyStyles({top:0});
//        }

        this.on('specialkey', this.onSpecialKey, this);
        this.df.el.swallowEvent(['keydown', 'keypress']);
        this.tf.el.swallowEvent(['keydown', 'keypress']);

        // create icon for side invalid errorIcon
        if('side' === this.msgTarget) {
            var elp = this.el.findParent('.x-form-element', 10, true);
            this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});

            var o = {
                 errorIcon:this.errorIcon
                ,msgTarget:'side'
                ,alignErrorIcon:this.alignErrorIcon.createDelegate(this)
            };
            Ext.apply(this.df, o);
            Ext.apply(this.tf, o);
//            this.df.errorIcon = this.errorIcon;
//            this.tf.errorIcon = this.errorIcon;
        }

        // setup name for submit
        this.el.dom.name = this.hiddenName || this.name || this.id;

        // prevent helper fields from being submitted
        this.df.el.dom.removeAttribute("name");
        this.tf.el.dom.removeAttribute("name");

        // we're rendered flag
        this.isRendered = true;

        // update hidden field
        this.updateHidden();

    } // eo function onRender
    // }}}
    // {{{
    
    ,adjustSize:Ext.BoxComponent.prototype.adjustSize
    // }}}
    // {{{
    
    ,alignErrorIcon:function() {
        this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
    }
    // }}}
    // {{{
    
    ,initDateValue:function() {
        this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
    }
    // }}}
    // {{{
    
    ,clearInvalid:function(){
        this.df.clearInvalid();
        this.tf.clearInvalid();
    } // eo function clearInvalid
    // }}}
    // {{{
    
    ,markInvalid:function(msg){
        this.df.markInvalid(msg);
        this.tf.markInvalid(msg);
    } // eo function markInvalid
    // }}}
    // {{{
    
    ,beforeDestroy:function() {
        if(this.isRendered) {
//            this.removeAllListeners();
            this.wrap.removeAllListeners();
            this.wrap.remove();
            this.tableEl.remove();
            this.df.destroy();
            this.tf.destroy();
        }
    } // eo function beforeDestroy
    // }}}
    // {{{
    
    ,disable:function() {
        if(this.isRendered) {
            this.df.disabled = this.disabled;
            this.df.onDisable();
            this.tf.onDisable();
        }
        this.disabled = true;
        this.df.disabled = true;
        this.tf.disabled = true;
        this.fireEvent("disable", this);
        return this;
    } // eo function disable
    // }}}
    // {{{
    
    ,enable:function() {
        if(this.rendered){
            this.df.onEnable();
            this.tf.onEnable();
        }
        this.disabled = false;
        this.df.disabled = false;
        this.tf.disabled = false;
        this.fireEvent("enable", this);
        return this;
    } // eo function enable
    // }}}
    // {{{
    
    ,focus:function() {
        this.df.focus();
    } // eo function focus
    // }}}
    // {{{
    
    ,getPositionEl:function() {
        return this.wrap;
    }
    // }}}
    // {{{
    
    ,getResizeEl:function() {
        return this.wrap;
    }
    // }}}
    // {{{
    
    ,getValue:function() {
        // create new instance of date
        return this.dateValue ? new Date(this.dateValue) : '';
    } // eo function getValue
    // }}}
    // {{{
    
    ,isValid:function() {
        return this.df.isValid() && this.tf.isValid();
    } // eo function isValid
    // }}}
    // {{{
    
    ,isVisible : function(){
        return this.df.rendered && this.df.getActionEl().isVisible();
    } // eo function isVisible
    // }}}
    // {{{
    
    ,onBlur:function(f) {
        // called by both DateField and TimeField blur events

        // revert focus to previous field if clicked in between
        if(this.wrapClick) {
            f.focus();
            this.wrapClick = false;
        }

        // update underlying value
        if(f === this.df) {
            this.updateDate();
        }
        else {
            this.updateTime();
        }
        this.updateHidden();

        // fire events later
        (function() {
            if(!this.df.hasFocus && !this.tf.hasFocus) {
                var v = this.getValue();
                if(String(v) !== String(this.startValue)) {
                    this.fireEvent("change", this, v, this.startValue);
                }
                this.hasFocus = false;
                this.fireEvent('blur', this);
            }
        }).defer(100, this);

    } // eo function onBlur
    // }}}
    // {{{
    
    ,onFocus:function() {
        if(!this.hasFocus){
            this.hasFocus = true;
            this.startValue = this.getValue();
            this.fireEvent("focus", this);
        }
    }
    // }}}
    // {{{
    
    ,onMouseDown:function(e) {
        if(!this.disabled) {
            this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
        }
    }
    // }}}
    // {{{
    
    ,onSpecialKey:function(t, e) {
        var key = e.getKey();
        if(key === e.TAB) {
            if(t === this.df && !e.shiftKey) {
                e.stopEvent();
                this.tf.focus();
            }
            if(t === this.tf && e.shiftKey) {
                e.stopEvent();
                this.df.focus();
            }
        }
        // otherwise it misbehaves in editor grid
        if(key === e.ENTER) {
            this.updateValue();
        }

    } // eo function onSpecialKey
    // }}}
    // {{{
    
    ,reset:function() {
        this.df.reset();
        this.tf.reset();
    } // eo function reset
    // }}}
    // {{{
    
    ,setDate:function(date) {
        this.df.setValue(date);
    } // eo function setDate
    // }}}
    // {{{
    
    ,setTime:function(date) {
        this.tf.setValue(date);
    } // eo function setTime
    // }}}
    // {{{
    
    ,setSize:function(w, h) {
        if(!w) {
            return;
        }
        if('below' === this.timePosition) {
            this.df.setSize(w, h);
            this.tf.setSize(w, h);
            if(Ext.isIE) {
                this.df.el.up('td').setWidth(w);
                this.tf.el.up('td').setWidth(w);
            }
        }
        else {
            this.df.setSize(w - this.timeWidth - 4, h);
            this.tf.setSize(this.timeWidth, h);

            if(Ext.isIE) {
                this.df.el.up('td').setWidth(w - this.timeWidth - 4);
                this.tf.el.up('td').setWidth(this.timeWidth);
            }
        }
    } // eo function setSize
    // }}}
    // {{{
    
    ,setValue:function(val) {
        if(!val && true === this.emptyToNow) {
            this.setValue(new Date());
            return;
        }
        else if(!val) {
            this.setDate('');
            this.setTime('');
            this.updateValue();
            return;
        }
        if ('number' === typeof val) {
          val = new Date(val);
        }
        else if('string' === typeof val && this.hiddenFormat) {
            val = Date.parseDate(val, this.hiddenFormat)
        }
        val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
        var da, time;
        if(val instanceof Date) {
            this.setDate(val);
            this.setTime(val);
            this.dateValue = new Date(Ext.isIE ? val.getTime() : val);
        }
        else {
            da = val.split(this.dtSeparator);
            this.setDate(da[0]);
            if(da[1]) {
                if(da[2]) {
                    // add am/pm part back to time
                    da[1] += da[2];
                }
                this.setTime(da[1]);
            }
        }
        this.updateValue();
    } // eo function setValue
    // }}}
    // {{{
    
    ,setVisible: function(visible){
        if(visible) {
            this.df.show();
            this.tf.show();
        }else{
            this.df.hide();
            this.tf.hide();
        }
        return this;
    } // eo function setVisible
    // }}}
    //{{{
    ,show:function() {
        return this.setVisible(true);
    } // eo function show
    //}}}
    //{{{
    ,hide:function() {
        return this.setVisible(false);
    } // eo function hide
    //}}}
    // {{{
    
    ,updateDate:function() {

        var d = this.df.getValue();
        if(d) {
            if(!(this.dateValue instanceof Date)) {
                this.initDateValue();
                if(!this.tf.getValue()) {
                    this.setTime(this.dateValue);
                }
            }
            this.dateValue.setMonth(0); // because of leap years
            this.dateValue.setFullYear(d.getFullYear());
            this.dateValue.setMonth(d.getMonth(), d.getDate());
//            this.dateValue.setDate(d.getDate());
        }
        else {
            this.dateValue = '';
            this.setTime('');
        }
    } // eo function updateDate
    // }}}
    // {{{
    
    ,updateTime:function() {
        var t = this.tf.getValue();
        if(t && !(t instanceof Date)) {
            t = Date.parseDate(t, this.tf.format);
        }
        if(t && !this.df.getValue()) {
            this.initDateValue();
            this.setDate(this.dateValue);
        }
        if(this.dateValue instanceof Date) {
            if(t) {
                this.dateValue.setHours(t.getHours());
                this.dateValue.setMinutes(t.getMinutes());
                this.dateValue.setSeconds(t.getSeconds());
            }
            else {
                this.dateValue.setHours(0);
                this.dateValue.setMinutes(0);
                this.dateValue.setSeconds(0);
            }
        }
    } // eo function updateTime
    // }}}
    // {{{
    
    ,updateHidden:function() {
        if(this.isRendered) {
            var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
            this.el.dom.value = value;
        }
    }
    // }}}
    // {{{
    
    ,updateValue:function() {

        this.updateDate();
        this.updateTime();
        this.updateHidden();

        return;
    } // eo function updateValue
    // }}}
    // {{{
    
    ,validate:function() {
        return this.df.validate() && this.tf.validate();
    } // eo function validate
    // }}}
    // {{{
    
    ,renderer: function(field) {
        var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
        format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
        var renderer = function(val) {
            var retval = Ext.util.Format.date(val, format);
            return retval;
        };
        return renderer;
    } // eo function renderer
    // }}}

}); // eo extend

// register xtype
Ext.reg('datetimefield', Ext.ux.form.DateTime);
Bt = {
	 version: '1.0'
	,layout	: {}
	,grid	: {}
	,form	: {}
	,util	: {}
};

//blank
Ext.BLANK_IMAGE_URL = 'extjs/resources/images/default/s.gif';
Ext.SSL_SECURE_URL = Ext.isIE && Ext.isSecure ? "javascript:''" : 'about:blank';

//ajax
Ext.Ajax.timeout = 120000;

//fields
Ext.form.Field.prototype.validationEvent = 'blur';

Ext.form.NumberField.prototype.allowDecimals = false;
Ext.form.NumberField.prototype.allowNegative = false;

//tree
Ext.tree.TreePanel.prototype.useArrows = true;

//grid
Ext.grid.GridPanel.prototype.stripeRows = true;

//gridview
Ext.grid.GridView.prototype.deferEmptyText = false;
Ext.grid.GridView.prototype.emptyText = Ext.PagingToolbar.prototype.emptyMsg;

Ext.onReady(function()
{
	Ext.QuickTips.init();
})




Bt.util.Format = {
	
	
    brMoney : function(v)
	{
		return Ext.util.Format.usMoney(v).replace('$','R$');
    }
	
	
};


Bt.require = function()
{
	var modulesLoaded = {};
	
	
	var createScriptTag = function( module, callback, scope)
	{
		//tira extens�o
		module = module.replace(/\.js/gi,"");
		
		//n�o carrega 2 vezes
		if( modulesLoaded[module] )
		{
	 		callback.call(scope,module);
			return;
		}
		modulesLoaded[module] = true;
		
		//cria tag e atributos
	    var script = document.createElement("script");
	    script.setAttribute('type','text/javascript');
		script.setAttribute('src',Bt.require.moduleUrl + module + '.js');
	
		//configura callback
		if(callback)
		{
		    if (script.readyState) //IE
			{  
		        script.onreadystatechange = function()
				{
		            if (/loaded|complete|4/i.test(script.readyState+""))
					{
		                callback.call(scope,module);
						script.onreadystatechange =callback = scope = null;
		            }
		        };
		    } 
			else //Others 
			{  
		        script.onload = function()
				{
		            callback.call(scope,module);
					script.onload = callback = scope = null;
		        };
		    }
		}
    	
		//append
   	 	document.getElementsByTagName("head")[0].appendChild(script);
	};
	
	
	var asyncProcess = function(modules, callback, scope)
	{
		this.totalToLoad = modules.length;
		this.totalLoaded = 0;
		this.finalCallback = callback||Ext.emptyFn;
		this.callbackScope = scope;
		
		for(var i = 0 ; i < modules.length ; i++ )
		{
			createScriptTag(modules[i], this.moduleCallback, this);
		}
	};
		 
	Ext.apply(asyncProcess.prototype,{
		
		 totalToLoad	: 0
		,totalLoaded	: 0
		,finalCallback	: Ext.emptyFn
		,callbackScope	: undefined
		
		,moduleCallback	: function(module)
		{
			this.totalLoaded++;
			
			if(window[module] && window[module].prototype && window[module].prototype.$depends)
			{
				var dependents = [].concat(window[module].prototype.$depends);
				
				//remove dos dependentes os j� carregados
				for(var i = dependents.length - 1 ; i != -1; i-- )
				{
					if (modulesLoaded[dependents[i]] === true) {
						dependents.pop();
					}
				}
				
				//se existe ainda dependentes para carregar
				if(dependents.length)
				{
					this.totalToLoad++;
					Bt.require(window[module].prototype.$depends,this.moduleCallback,this);
				}
			}
			
			if(this.totalLoaded == this.totalToLoad)
			{
				this.finalCallback.call(this.callbackScope);
				
				//destroy
				for (k in this) {
					this[k] = null;
				}
			}
		}
	});
	
	
	
	this.reload = function(module)
	{
		delete modulesLoaded[module];
		createScriptTag(module);
	};
	
	
	return function (modules, callback, scope)
	{
		if (!Ext.isArray(modules)) {
			modules = [modules];
		}
		
		new asyncProcess(modules, callback, scope);
	};
}();


Bt.require.moduleUrl = 'jscripts/';
Bt.Button = Ext.extend(Ext.Button, {
	
	//Overrides {
	
		onDestroy: function()
		{
			Bt.Button.superclass.onDestroy.apply(this,arguments);
			
			if(this._errorTip)this._errorTip.hide();
			if(this._successTip)this._successTip.hide();	
			
			delete this._errorTip;
			delete this._successTip;
		}
	
	//}
	
	//Demais m�todos {
	
	    ,setLoading: function(loading)
		{
	        if (loading) 
			{
	            this._iconCls = this.iconCls;
	            this.setIconClass('ico-loading')
	            this.disable();
	        }
	        else 
			{
	            this.setIconClass(this._iconCls)
	            delete this._iconCls;
	            this.enable();
	        }
	    }
		
		,showErrorTip: function(msg, anchor)
		{
			this._errorTip = Bt.QuickTips.showError(this.el,msg,anchor);
		}
		
		,showSuccessTip: function(msg, anchor)
		{
			this._successTip = Bt.QuickTips.showSuccess(this.el,msg,anchor);
		}
	
	//}
	
});

Ext.reg('bt-button',Bt.Button);
Bt.IframePanel = Ext.extend(Ext.Container,{
	
	//Config Options {
	
		 initialized: false
		,editable	: false
		,src		: Ext.isIE ? Ext.SSL_SECURE_URL : "javascript:;"
		
	//}
	
	//Inits {
	
		,constructor: function(cfg)
		{
			cfg = cfg||{};
			
			this.autoEl	= {
				 tag		: 'iframe'
		        ,frameBorder: '0'
				,name		: Ext.id()
		        ,src 		: cfg.src||this.src
			}
			
			Bt.IframePanel.superclass.constructor.apply(this,arguments);		
		}
	
	//}
	
	//Acessores {
	
		,setSrc: function(src)
		{
			this.src = src;
			if(this.el)
			{
				this.el.dom.src = src;
			}
		}
	
	//}
	
	//Overrides {
	
		,onDestroy: function()
		{
			Bt.IframePanel.superclass.onDestroy.apply(this,arguments);
			delete this.iframe;
		}
		
		,onRender: function()
		{
			Bt.IframePanel.superclass.onRender.apply(this,arguments);
			
			this.iframe = this.el.dom
	
			this.win = this.getWin();
			this.doc = this.getDoc();
	        
			if(this.editable)
			{
	        	this.doc.open();
	        	this.doc.write(this.getDocMarkup());
	        	this.doc.close();
			}
			
			var task = { // must defer to wait for browser to be ready
				 interval	: 10
	            ,duration	: 10000
	            ,scope		: this
				,run 		: function()
				{
	                if( this.getWin() && this.getDoc() && this.getEditorBody())
					{
	                    Ext.TaskMgr.stop(task);
	                    this.doc.designMode="off";
						this.initEditor.defer(10, this);
	                }
	            }
	        };
	        Ext.TaskMgr.start(task);
		}
	
	//}
	
	//Demais m�todos {
		
	    ,pushValue : function( value )
		{
			if(!this.editable)
				return false;
				
			this.value = value;
	        
			if(this.initialized)
			{
            	this.getEditorBody().innerHTML = value;
	     
		        if(Ext.isGecko)
				{
	                this.doc.designMode = 'on';
					this.doc.designMode = 'off';
	            }
	        }
	    }
	
		,getDocMarkup : function(){
	        return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
	    }
		
		,getEditorBody : function(){
	        return this.doc.body || this.doc.documentElement;
	    }
	
	    ,getDoc : function(){
	        return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
	    }
	
	    ,getWin : function(){
	        return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
	    }
		
		,initEditor : function()
		{
			if(!this.editable)
			{
				this.initialized = true;
				return true;
			}
			else
			{
		        //Destroying the component during/before initEditor can cause issues.
		        try{
		            var dbody = this.getEditorBody();
		            var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
		            ss['background-attachment'] = 'fixed'; // w3c
		            dbody.bgProperties = 'fixed'; // ie
		
		            Ext.DomHelper.applyStyles(dbody, ss);
		
		            if(this.doc){
		                try{
		                    Ext.EventManager.removeAll(this.doc);
		                }catch(e){}
		            }
		
		            this.doc = this.getDoc();
		
		            this.initialized = true;
		            this.doc.editorInitialized = true;
		            this.pushValue(this.value);
		        }catch(e){}
			}
	    }
	
	//}
	
});
Ext.reg('bt-iframe',Bt.IframePanel);
Bt.LinkPanel = Ext.extend(Ext.Panel,{
	
	//Inits {
	
		initComponent: function()
		{
			//autoLoad
			if( this.autoLoad )
			{
				this.autoLoadLink = this.autoLoad;
				this.autoLoad = undefined;
				
				if(typeof this.autoLoadLink == 'string' )
				{
					this.autoLoadLink = {
						url: this.autoLoadLink
					}
				}
			}
			
			
			//config.
			Ext.apply(this,{
				 layout			: 'links'
				,defaults		: Ext.apply(this.defaults||{},{
					border: false
				})
				,layoutConfig	: Ext.apply( this.layoutConfig||{} , {
					animate:true
				})
			});
			
			//super
			Bt.LinkPanel.superclass.initComponent.call(this);
		}
			
	//}
	
	//Overrides {
	
		,onRender:function() 
		{
	    	//super  
	        Bt.LinkPanel.superclass.onRender.apply(this, arguments);
	
			if(this.autoLoadLink)//meta panel
			{	
				Ext.Ajax.request({
					 url		: this.autoLoadLink.url
		            ,method		: 'GET'
					,params		: Ext.apply({},this.autoLoadLink.params,{meta:true})
					,scope		: this
					,callback	: this.doAutoLoad
				});
			}
	    }
		
	//}
	
	//Demais m�todos {
	
	    ,doAutoLoad:function( elUpdate, success , response , options , initialConfig )
		{
			//remove todos elementos
			while( this.items.getCount() != 0 )
				this.remove(0);
			
			//trata resposta
			var items = Ext.util.JSON.decode(response.responseText);
	
			//itera sobre os items
	        for(var i = 0; i < items.length; i++)
			{
				//aplica defaults
				Ext.applyIf(items[i],this.defaults);
				
				//adiciona items
		        this.add(items[i])
	        }
			
			//refaz layout
	       	this.doLayout();
	
			//chama callback se tiver
			if( this.autoLoadLink.callback )
				this.autoLoadLink.callback.apply(this||this.autoLoadLink.scope,arguments)
	    }
		
	//}
});

//Registra
Ext.reg('bt-linkpanel',Bt.LinkPanel);


Bt.layout.LinksLayout = function(config) {
	
	Ext.apply(this, config);
	

    Bt.layout.LinksLayout.superclass.constructor.call(this);
};

Ext.extend(Bt.layout.LinksLayout,Ext.layout.Accordion,{
	
	
	activeLink:-1
	
	,activeHover:true
	
	
	,renderItem : function( linkItem , index )
	{
		//if the link doesn�t have any items, it�s a simple link, else, is a groupping
		var isSimpleLink = (!linkItem.items)?true:false;
		
		//call beforeRender functions		
		if( isSimpleLink )
		{
			this.beforeRenderSimplyLink( linkItem );
		}			
		else
		{
			this.beforeRenderGroupingLink( linkItem );
		}
		
		//close link by default
		linkItem.collapsed=true;
		
		//If the item is the activeItem, and the item is a groupping item
		if( index == this.activeLink && !isSimpleLink )
			linkItem.collapsed = false;  //...expand this item
	
		//call super render
		Bt.layout.LinksLayout.superclass.renderItem.apply(this,arguments);
		
		//call afterRender functions
		if( isSimpleLink )
		{
			this.afterRenderSimplyLink( linkItem );
		}			
		else
		{
			this.afterRenderGroupingLink( linkItem );
		}
		
		//add hover cls
		if(this.activeHover)
			linkItem.header.addClassOnOver('bt-linkPanel-hover');
	}
	
	
	,beforeRenderSimplyLink : function( simpleLink )
	{
		simpleLink.cls='bt-linkPanel-simpleLinkPanel';	//add css
		
		if(!this.initialConfig)this.initialConfig={};
		this.initialConfig.titleCollapse = this.titleCollapse; 	//save the state of titleCollapse
		this.titleCollapse = false; 							//turn it off
		
		simpleLink.hideCollapseTool = true;//remove collapse/expand icon
	}
	
	
	,beforeRenderGroupingLink : function( groupingLink )
	{
		groupingLink.items.each(function(item){
		
			item.cls='bt-groupLinkPanel-body';
		
		},this);
	}
	
	
	,afterRenderSimplyLink:function( simpleLink )
	{
		this.addLinkClickEvent( simpleLink );//add click event
		
		this.titleCollapse = this.initialConfig.titleCollapse;//set back the titleCollapse value;
	}
	
	
	,afterRenderGroupingLink: function(groupingLink){
		
		//if panel type form return
		if(groupingLink.xtype == 'form')
			return;
		
		this.addLinkClickEvent( groupingLink );//add click event
		
		//add the handler to the underlying Ext.element after the component is rendered
		groupingLink.items.each(function(item){
			
			this.addLinkClickEvent( item );
			
			if (this.activeHover) 
				item.on('render', function(item){ item.header.addClassOnOver('bt-linkPanel-hover'); }, this);
			
		
		},this);
	}
	
	
	,addLinkClickEvent : function( link )
	{
		var handler = link.initialConfig.handler;
		var scope   = link.initialConfig.scope||link;
		
		if(!handler)
			return;
		
		if( link.header )
			link.header.on('click', handler.createDelegate(scope,[link]) ,link,scope);
		else
			link.on('render',function(){ link.header.on('click',handler.createDelegate(scope,[link])); },link)
	}
});

Ext.Container.LAYOUTS['links'] = Bt.layout.LinksLayout;
Bt.LoginWindow = Ext.extend(Ext.Window,{

	//Config Options {
	 	
		//LoginWindow
		 url				: undefined
		,params				: undefined
		,redirectUrl		: undefined
		,inputLoginName		: 'usuario'
		,inputPasswordName	: 'senha'
				
		//super
		,title		: 'Autentica&#231;&#227;o'
		,baseCls	: 'x-panel'
		,cls		: 'bt-loginWindow'
		,layout		: 'form'
		,bodyStyle	: 'padding:10px;'
		,iconCls	: 'lock'
		,labelAlign	: 'right'
		,closable 	: false
		,border		: false
		,constrain	: true
		,width		: 330
		,height		: 150
		,labelWidth	: 60
				
	//}
	
	//Inits {
		
		,initComponent: function()
		{
			//config.
			Ext.apply(this,{
				 defaults:{
				  	 width			: 200
					,allowBlank		: false
					,enableKeyEvents: true
					,listeners		: {
						 scope: this
						,keyup: this._onFieldKeyUp
					}
				 }
				,items:[{
					 xtype		: 'textfield'
					,fieldLabel	: 'Usu&#225;rio'
					,name		: this.inputLoginName
				},{
					 xtype		: 'textfield'
					,fieldLabel	: 'Senha'
					,inputType	: 'password'
					,emptyText	: 'fakepass'
					,name		: this.inputPasswordName
				}]
				,buttons:[{
					 xtype		: 'bt-button'
					,text		: 'Login'
					,iconCls	: 'application-go'
					,scope		: this
					,handler	: this._onBtnLoginClick
					,listeners	: {
						 scope	: this
						,single	: true
						,render	: this._onBtnLoginRender
					}
				}]
			})
			
			//super
			Bt.LoginWindow.superclass.initComponent.call(this);
		}
		
		,initEvents: function()
		{
			//super
			Bt.LoginWindow.superclass.initEvents.call(this);
			
			this.on({
				 scope		: this
				,single		: true
				,delay		: 1000
				,afterlayout: this._onAfterLayout
			});
		}
		
	//}
	
	//Overrides {
	
		,onDestroy: function()
		{
			//super
			Bt.LoginWindow.superclass.onDestroy.apply(this,arguments);
			
			Ext.destroy(this.proxy);
			this.proxy = null;
		}
		
		,show: function()
		{
			//super
			Bt.LoginWindow.superclass.show.apply(this,arguments);
			
			//verifica erro via URL
	    	var request = window.location.href.split('?')[1];
			if(request)
			{
		        request = Ext.urlDecode(request);
				if(request['loginError'])
					this.buttons[0].showErrorTip(Bt.LoginWindow.loginErrors[request['loginError']]);
		    }
		}
	
	//}
	
	//Listeners {
		
		,_onAfterLayout: function()
		{
			//foco
			this.get(0).focus();
		}
		
		,_onBtnLoginRender: function()
		{
			
		}
		
		,_onFieldKeyUp: function(field, e)
		{
			if(e.getKey() === e.ENTER )
			{
				this._onBtnLoginClick();
				e.stopEvent();
			}
		}
		
		,_onBtnLoginClick: function()
		{
			//validate and value
			var isValid = true;
			var values = {};
			
			this.items.each(function(item)
			{
				if(!item.isValid())
					isValid = false;
					
				if(isValid && item.name)
					values[item.name] = item.getValue();
			})
			
			if(!isValid)
				return;
			
			this.buttons[0].setLoading(true);
			
			//request
			Ext.Ajax.request({
				 url	: this.url 
				,params	: Ext.apply(this.params||{},values)
				,scope	: this
				,failure: function()
				{
					this.buttons[0].showErrorTip('N&#227;o foi poss&#237;vel contactar o servidor')	
				}
				,callback: function()
				{
					this.buttons[0].setLoading(false);
				}
				,success: function(response)
				{
					try{
					
						//converte resposta
						response = Ext.decode(response.responseText);
						
						//valida resposta
						if( response.success === true )
						{
							this.disable();
							window.location.href = this.redirectUrl;
						}
						else
						{
							this.buttons[0].showErrorTip(response.message||"Usu&#225;rio e/ou senha inv&#225;lidos");	
						}
					}
					catch(e)
					{
						//json inv�lido
						this.buttons[0].showErrorTip('Erro ao receber resposta do servidor');	
						return;
					}
				}
			});	
		}
	
	//}
	
	
});


Bt.LoginWindow.loginErrors = {
	1: 'A sess&#227;o expirou, refa&#231;a o login'
}

Bt.QuickTip = Ext.extend(Ext.QuickTip,{
	
	//Overrides {
		
		 onTargetOver	: Ext.emptyFn
		,onTargetOut	: Ext.emptyFn
		,onMouseMove	: Ext.emptyFn
		
		,showAt: function()
		{
			if(this.anchor)
			{
	            // pre-show it off screen so that the el will have dimensions
	            // for positioning calcs when getting xy next
	            Bt.QuickTip.superclass.showAt.call(this,[-1000,-1000]);
	            this.origConstrainPosition = this.constrainPosition;
	            this.constrainPosition = false;
	            this.anchor = this.origAnchor;
	        }
			
			//super
			Bt.QuickTip.superclass.showAt.apply(this,arguments);
			
			if(this.anchor){
	            this.syncAnchor();
	            this.anchorEl.show();
	            this.constrainPosition = this.origConstrainPosition;
	        }else{
	            this.anchorEl.hide();
	        }
		}
	
	//}
	
	//Acessores {
	
		,setText: function(text)
		{
			if(this.text === text)
				return;
				
			this.text = text;
			
			if(this.rendered)
				this.body.update(text);
		}
		
		,setAnchor: function(anchor)
		{
			if(this.anchor === anchor)
				return;
				
			//remove
			this.anchorEl.removeClass('x-tip-anchor-'+this.getAnchorPosition());
			
			//update
			this.anchor = this.origAnchor = anchor;
			this.tipAnchor = this.anchor.charAt(0);
			this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
			this.anchorEl.addClass(this.anchorCls);
		}
	
	//}
	
	
});
Bt.QuickTips = {
	
	//Demais m�todos 
		
		showSuccess: function(xy, text, anchor)
		{	
			//create
			if(!this.successTip)
			{
				this.successTip = new Bt.QuickTip({
					 cls			: 'bt-valid-tip'
					,disabled		: true
					,autoHide		: false
					,onTargetOver	: Ext.emptyFn
					,onTargetOut	: Ext.emptyFn
					,onMouseMove	: Ext.emptyFn
					,target   		: Ext.getBody()
					,renderTo		: Ext.getBody()
				});
			}
	
			//update
			this.successTip.setAnchor(anchor||'right');
			this.successTip.setText(text);
		
			//show
			if(Ext.isArray(xy))
			{
				this.successTip.showAt(xy);
				this.successTip.anchorEl.show();	
			}
			else
			{
				this.successTip.anchorTarget = xy;
				this.successTip.show();
			}
			
			return this.successTip; 
		}
		
		,showError: function(xy, text, anchor)
		{	
			//create
			if(!this.errorTip)
			{
				this.errorTip = new Bt.QuickTip({
					 cls			: 'x-form-invalid-tip'
					,disabled		: true
					,autoHide		: false
					,onTargetOver	: Ext.emptyFn
					,onTargetOut	: Ext.emptyFn
					,onMouseMove	: Ext.emptyFn
					,target   		: Ext.getBody()
					,renderTo		: Ext.getBody()
				});
			}
	
			//update
			this.errorTip.setAnchor(anchor||'right');
			this.errorTip.setText(text);
		
			//show
			if(Ext.isArray(xy))
			{
				this.errorTip.showAt(xy);
				this.errorTip.anchorEl.show();	
			}
			else
			{
				this.errorTip.anchorTarget = xy;
				this.errorTip.show();
			}
			
			return this.errorTip; 
		}
		
	//}
	
};
Bt.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
	
	
	//Config Options {
		
		 header		: 'A&#231;&#245;es'
		,fixed		: true
		
	//}
	
	//Inits {
		
		,constructor : function(cfg)
		{
			cfg = cfg||{};
			
			if(Ext.isArray(cfg))
			{
				cfg = {actions:cfg}
			}
			
			Ext.apply(cfg,{
				 dataIndex		: ''
				,align			: 'center'
				,sortable		: false
				,menuDisabled	: true
				,scope			: this
				,width			: 100
			})

			//super
			Bt.grid.ActionColumn.superclass.constructor.call(this,cfg)
		}
		
		,init: function(grid)
		{
			var me = this;
			this.grid = grid;
	
			//tpl
			this.tpl = [];
			for(var i = 0; i < this.actions.length ; i++ )
			{
				this.tpl.push('<img width="16" height="16" ');
				
				if(typeof this.actions[i].disabled === 'string')
				{
					this.tpl.push(
						'<tpl if="'+this.actions[i].disabled+'">' +
							' class="x-item-disabled '+ this.actions[i].iconCls +'" qtip="'+ this.actions[i].disabledTip +'" disabled="disabled"' +
						'</tpl>' +
						'<tpl if="!'+this.actions[i].disabled+'">' +
							' class="bt-row-action bt-pointer '+ this.actions[i].iconCls +'" qtip="'+ this.actions[i].qtip +'" ' +
						'</tpl>'	
					);	
				}
				else
				{
					this.tpl.push(' class="bt-row-action bt-pointer '+ this.actions[i].iconCls +'" qtip="'+ this.actions[i].qtip +'" ');	
				}
				
				this.tpl.push(' src="'+ Ext.BLANK_IMAGE_URL +'" /> ');
			}
			this.tpl = this.tpl.join('');
			this.tpl = new Ext.XTemplate(this.tpl);
			this.tpl.compile();
			
			//evento click
			grid.afterRender = grid.afterRender.createSequence(function()
			{
				grid.view.mainBody.on('click',me.onGridClick,me);
			});
			
			//destroy
			grid.on('destroy', this.onGridDestroy, this);
	    }
	
	//}
	
	//Override {
	
		,renderer: function(a,b,r)
		{
			return this.tpl.applyTemplate(r.data);
		}
	
	//}
	
	//Listeners{
	
		,onGridDestroy: function()
		{
			delete this.grid;
		}
		
		,onGridClick: function(e)
		{
			var target = e.getTarget(undefined,undefined,true);
			var targetRow = e.getTarget('.x-grid3-row');
			e.stopEvent();
			
			//verifica se � �cone de a��o
			if( target.is('img.bt-row-action') )
			{
				//busca record
				var rowIndex = this.grid.view.findRowIndex( targetRow );
				if(rowIndex === false)return;
				var record = this.grid.store.getAt(rowIndex);
					
				//busca iconCls
				var iconCls = target.dom.className.replace(/bt-row-action/, '').replace(/bt-pointer/,'').trim();
				
				//busca a��o
				var action;
				for(var i = 0 ; i < this.actions.length ; i++ )
				{
					if(iconCls === this.actions[i].iconCls)
					{
						action = this.actions[i];
						break;
					}
				}
				
				//dispara
				if( action )
					action.handler.call(action.scope||this,this.grid,record,rowIndex);
			}
		}
	
	//}
	
});

Ext.preg('bt-actioncolumn',Bt.grid.ActionColumn);
Bt.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
	
	//Config Options {
		
		 header		: '&nbsp;'
		,dataIndex	: ''
		,sortable	: false
		,fixed		: true
			
	//}
	
	//Inits {
		
		,constructor : function(cfg)
		{
			Ext.apply(cfg,{
				 align			: 'center'
				,menuDisabled	: true
				,width			: 100
			})

			//super
			Bt.grid.BooleanColumn.superclass.constructor.call(this,cfg)
		}
	//}
	
	//Override {
	
		,renderer: function(v)
		{
			return '<img src="'+ Ext.BLANK_IMAGE_URL +'" width="16" height="16" class="ico-check-'+(v ? 'true' : 'false')+'" />';
		}
	
	//}
	
});

Ext.grid.Column.types['b-boolean'] = Bt.grid.BooleanColumn;
Bt.grid.EnableColumn = Ext.extend(Ext.grid.Column, {
	
	
	
	
	
	
	//Config Options {
		
		 header		: 'Habilitado'
		,dataIndex	: 'habilitado'
		,css		: 'cursor: pointer;'
		,url		: ''
		,align		: 'center'
		,sortable	: false
		,params		: undefined
		,disable	: ''
		,disableTip	: ''
		,paramsAsHash: false
					
	//}
	
	//Inits {
		
		,constructor : function(cfg)
		{
			Ext.apply(cfg,{
				 align			: 'center'
				,menuDisabled	: true
				,width			: 100
			})

			//super
			Bt.grid.EnableColumn.superclass.constructor.call(this,cfg)
		}
		
		,init: function(grid)
		{
			var me = this;
			this.grid = grid;
	
			//evento click
			grid.afterRender = grid.afterRender.createSequence(function()
			{
				grid.view.mainBody.on('click',me.onGridClick,me);
			});
			
			//destroy
			grid.on('destroy', this.onGridDestroy, this);
	    }
	
	//}
	
	//Override {
	
		,renderer: function(v,m,r)
		{
	
			var disabled = (this.disable && r.data[this.disable] === true) ? 'x-item-disabled' : '';
			var disableTip = disabled ? this.disableTip : '';
			 
			return '<img src="'+ Ext.BLANK_IMAGE_URL +'" width="16" height="16" qtip="'+ disableTip +'" class="'+disabled+' ico-check-'+(v ? 'true' : 'false')+'" />';
		}
	
	//}
	
	//Listeners{
	
		,onGridDestroy: function()
		{
			delete this.grid;
		}
		
		,onGridClick: function(e)
		{
			var target = e.getTarget(undefined,undefined,true);
			var targetRow = e.getTarget('.x-grid3-row');
			e.stopEvent();
			
			//verifica se � �cone de a��o
			if( target.is('img.ico-check-true') || target.is('img.ico-check-false') )
			{
				//deve estar habilitado
				if(target.hasClass('x-item-disabled'))
				{
					return;
				}
			
				//busca record
				var rowIndex = this.grid.view.findRowIndex( targetRow );
				if(rowIndex === false){return;}
				var record = this.grid.store.getAt(rowIndex);
				
				//verifica a��o
				var isHabilitar = (record.get(this.dataIndex) !== true);
					
				//pergunta
				Ext.Msg.confirm('Confirma&#231;&#227;o','Deseja ' + (isHabilitar?'habilitar':'desabilitar') + ' este registro?',function(opt)
				{
					if(opt==='no'){
						return;
					}
					
					this.grid.el.setLoading(isHabilitar ? 'Habilitando registro' : 'Desabilitando registro');
					
					var success = function()
					{
					 	this.grid.el.setLoading(false);
						record.set(this.dataIndex,isHabilitar);
						record.store.commitChanges();
					};
					 
					if(this.directFn)
					{
						var params;
						
						if(this.paramsAsHash)
						{
							params =  Ext.apply({},this.params);
							params[this.dataIndex] = isHabilitar;
							params[record.store.idProperty] = record.id;
					
							this.directFn(params,success,this);
						}
						else						
						{
							
							params =  [record.id,isHabilitar];
							for(var k in this.params)
							{
								params.push(this.params[k]);
							}
							
							params.push(success);
							params.push(this);
							
							this.directFn.apply(this.directFn,params);
						}
					}
					else
					{
						//lan�a requisi��o
						Ext.Ajax.request({
							  url		: this.url
							 ,params	: params
							 ,scope		: this
							 ,success	: success
						});
					}
							
				},this)
			}
		}
	
	//}
	
});

Ext.preg('bt-enablecolumn',Bt.grid.EnableColumn);
Bt.grid.GridPanel = Ext.extend(Ext.grid.EditorGridPanel,{
	
	
	
	
	
	
	
	
	
	//Config Options {
	
		//Bt.grid.GridPanel
		 paging			: false
		,editable		: false
		,actions		: false
		,rowEditor		: false
		,rowExpander	: false
		,filter			: false
		,quickFilter	: false
		,linkable		: false
		,enableColumn	: false
		,autoSizeColumns: true
		,trackMouseOver	: true
		
		
		//super
		,loadMask	: true
		
	//}
	
	//Inits {
		
		,constructor: function(cfg)
		{
			//filter
			if(this.filter || (cfg && cfg.filter) )
			{
				this.filter = this._addPlugin(new Bt.grid.GridFilter());
			}
			
			//super
			Bt.grid.GridPanel.superclass.constructor.apply(this, arguments);
		}
		
		,initComponent: function()
		{
			//cria pagina��o
			if(this.paging)
			{
				var pagingConfig = {
					 store		: this.store
					,displayInfo: true
					,pageSize	: 15
				}
				
				if(Ext.isObject(this.paging))
					Ext.apply(pagingConfig,this.paging);
		
				this.bbar = new Ext.PagingToolbar(pagingConfig);
			}
			
			//edit�vel
			if( this.editable === true && this.rowEditor )
			{
				this.rowEditor = this._addPlugin(
					new Ext.ux.grid.RowEditor()
				);
				
				if(this.onRowEditorAfterEdit){
					this.rowEditor.on('afteredit',this.onRowEditorAfterEdit,this);
				}	
				
				if(this.onRowEditorCancelEdit){
					this.rowEditor.on('canceledit',this.onRowEditorCancelEdit,this);
				}	
				
				if(this.onRowEditorHide){
					this.rowEditor.on('hide',this.onRowEditorHide,this);
				}
			}
			
			if( this.editable === false || this.rowEditor )
			{
				this.selModel = new Ext.grid.RowSelectionModel();
			}
			
			//actions
			if( this.actions )
			{
				//default actions
				if( !Ext.isArray(this.actions) && !this.actions.actions )
				{
					var actions = [];
					
					if(this.actions.visualize !== false)
					{
						actions.push({
							 iconCls	: 'ico-form-visualizar'
							,qtip		: 'Visualizar'
							,disabled	: this.actions.disableVisualize
							,disabledTip: this.actions.disableVisualizeTip
							,scope		: this.actions.scope||this
							,handler	: this.onVisualizeClick
						})
					}
					
					if( this.actions.edit !== false )
					{
						actions.push({
							 iconCls	: 'ico-form-editar'
							,qtip		: 'Editar'
							,disabled	: this.actions.disableEdit
							,disabledTip: this.actions.disableEditTip
							,scope		: this.actions.scope||this
							,handler	: this.onEditClick
						});
					}
					
					if( this.actions.remove !== false )
					{
						actions.push({
							 iconCls	: 'ico-form-remover'
							,qtip		: 'Excluir'
							,disabled	: this.actions.disableRemove
							,disabledTip: this.actions.disableRemoveTip
							,scope		: this.actions.scope||this
							,handler	: this.onRemoveClick
						});
					}
					
					this.actions = actions;
				}
				
				this.actions = this._addColumn(
					this._addPlugin(
						new Bt.grid.ActionColumn(this.actions)
					)
				,true);
			}
			
			//enable column
			if( this.enableColumn )
			{
				this.enableColumn = this._addColumn(
					this._addPlugin(
						new Bt.grid.EnableColumn(this.enableColumn)
					)
				);
			}
			
			//expander
			if(this.rowExpander)
			{
				if(Ext.isObject(this.rowExpander))
				{ 
					this.rowExpander = new Ext.ux.grid.RowExpander(this.rowExpander);
				}
				else if(Ext.isString(this.rowExpander))
				{
					this.rowExpander = new Ext.ux.grid.RowExpander({
						tpl:  new Ext.Template('<div class="bt-selectable" style="padding:5px 5px 20px 5px;">{'+ this.rowExpander +'}</div>')
					});
				}
				
				this._addColumn(
					this._addPlugin(this.rowExpander)
				,true);
			}
			
			//quickfilter
			if(this.quickFilter)
			{
				if(!this.bbar || !this.bottomToolbar)
					this.bbar = [];
					
				this.quickFilter = this._addPlugin(new Ext.ux.grid.Search({
					
				}))
			}
			
			//super
			Bt.grid.GridPanel.superclass.initComponent.call(this);
			
			//auto expand
			if( this.autoSizeColumns )
			{
				this.store.on('load',this._doAutoSizeColumns,this);
			}
			
			//colunas link�veis
			Ext.each(this.getColumnModel().config,function(coluna)
			{
				if(coluna.handler)
				{
					this.on('cellclick',this._onCellClick,this);
				}
					 
			},this);
		}
	
	//}
	
	//Overrides {
	
		,onDestroy: function()
		{
			Ext.destroy(this.actions, this.rowEditor, this.filter, this.quickFilter)
			this.actions = this.rowEditor = this.filter = this.rowExpander = 
			this.filter = this.quickFilter = null;
			
			//super
			Bt.grid.GridPanel.superclass.onDestroy.apply(this,arguments);
		}
	
	//}
	
	//Listeners {
	
		
		,onVisualizeClick:Ext.emptyFn
		
		
		,onEditClick:Ext.emptyFn
		
		
		,onRemoveClick:Ext.emptyFn
		
		
		,onRowEditorAfterEdit:Ext.emptyFn
	
		,_onCellClick: function(me, rowIndex, columnIndex, e)
		{
			var coluna = this.getColumnModel().config[columnIndex];
			if( coluna && coluna.handler )
			{
				var record = this.getStore().getAt(rowIndex);
				coluna.handler.call(coluna.scope||this,me,record,rowIndex,columnIndex,e);
			}
		}
	//}
	
	//Demais m�todos {
	
		,_addPlugin: function( plugin )
		{
			if (!this.plugins) {
				this.plugins = [];
			}else{
				if( !Ext.isArray(this.plugins) )	
					this.plugins = [this.plugins];
			}
			
			this.plugins.push( plugin );	 
			return plugin;
		}
		
		,_addColumn: function( column, isFirst )
		{
			var cm = this.colModel||this.cm||this.columns;
			
			if(Ext.isArray(cm))
			{
				cm[isFirst? 'unshift' : 'push']( column );
			}
			else
			{
				var columns = cm.columns||cm.config;
				columns[isFirst? 'unshift' : 'push']( column );
				
				cm.setConfig(columns, true);
			}
			
			return column;
		}
		
		,_doAutoSizeColumns: function()
		{
			if( !this.view )
				return;
			
			var w=0, j=0
				,i = this.colModel.getColumnCount()
				,storeCount = this.store.getCount();
			
			while(i--)
			{
		    		var col = this.view.getHeaderCell(i);
					
					if(!col || this.colModel.isFixed(i))
						continue;
					
					var w = col.firstChild.scrollWidth;
					
					j = storeCount;
					while(j--) 
						w = Math.max(w, this.view.getCell(j,i).firstChild.scrollWidth);
				
				this.colModel.setColumnWidth(i, w+2);
	  	  	}
		}
	
	//}
	
	
});
Ext.reg('bt-grid',Bt.grid.GridPanel)

Bt.grid.GridFilter = Ext.extend(Ext.Window,{
	
	//Config Options {
	
		 iconCls	: 'ico-lupa'
		,title		: 'Filtro'
		,closeAction: 'hide'
		,layout		: 'form'
		,bodyStyle	: 'padding:10px;'
		,labelAlign	: 'top'
		,modal		: true
		,constrain	: true
		,autoScroll	: true
		,width		: 10
		,height		: 10
		
	//}
	
	//Inits {
	
		,init: function( grid )
		{
			this.grid = grid;
			var filter;
			
			Ext.each(this.grid.getColumnModel().config,function( objColuna )
			{
				filter = objColuna.filter;
				delete objColuna.filter;
				
				if( filter )
				{
					if(Ext.isString(filter))
					{
						if(Bt.grid.GridFilter.Filters[filter])
						{
							filter = Ext.apply({},Bt.grid.GridFilter.Filters[filter]);
						}
						else if(Ext.ComponentMgr.isRegistered(filter))
						{
							filter = {xtype: filter};
						}	
					}
					
					Ext.applyIf(filter,{
						 fieldLabel	: objColuna.header
						,name		: objColuna.dataIndex
						,width		: 300	
					});
				
					this.width  = Math.max(this.width,filter.width+20) + 20;
					this.add(filter);
				}
				
			},this);
			
			if(this.items)
				this.height = Math.max(this.height,this.items.length * 44) + 24 + 44 + 30;
		}
		
		,initComponent: function()
		{
			Ext.apply(this,{
				buttons:[{
					 text	: 'Cancelar'
					,iconCls: 'ico-cancela'
					,scope	: this
					,handler: function(){ this.hide(); }
				},{
					 text	: 'Aplicar'
					,iconCls: 'ico-aceita'
					,scope	: this
					,handler: this._onBtnAceitaClick
				}]	
			});
			
			Bt.grid.GridFilter.superclass.initComponent.call(this);
		}
	
	//}
	
	//Overrides {
	
		,render : function()
		{
			Bt.grid.GridFilter.superclass.render.call(this, this.grid.el);
		}
	
	//}
	
	//Listeners {
	
		,_onBtnFilterClick: function()
		{
			this.fitGridBody();
			this.show();
		}
		
		,_onBtnAceitaClick: function()
		{
			var values = {};
			var value;
			this.items.each(function( item )
			{
				if( !values || !item.isValid() )
					values = false;
				else
				{	
					value = item.getValue();
					
					if(value !== "" && value !== 0)
					{
						values[item.name] = value;

						if(Ext.isDate(values[item.name]))
							values[item.name] = values[item.name].format('Y-m-d H:i:s');
					}
				}
					
			});
	
			if(values === false )
				return false;
			
			this.grid.store.baseParams = Ext.apply(this.grid.store.baseParams||{},values); 
			this.grid.store.reload();
			
			this.hide();
			this._btnLimpaFiltro.show();
		}
		
		,_onBtnLimpaFiltroClick: function()
		{
			var store 	= this.grid.store;
			var isFilter= false;
			
			if(store.baseParams)
			{
				Ext.each(this.grid.getColumnModel().config,function( objColuna )
				{
					if( store.baseParams[objColuna.dataIndex])
					{
						delete this.grid.store.baseParams[objColuna.dataIndex];
						isFilter = true;
					}
				},this);	
				
				if(isFilter)
					store.reload();
			}
			
			this._btnLimpaFiltro.hide();
		}
	
	//}
	
	//Demais m�todos {
	
		,getToolbarButton: function()
		{
			this._btnLimpaFiltro = new Ext.Toolbar.Button({
				 iconCls: 'ico-cross'
				,text	: 'Limpar filtro'
				,hidden	: true
				,scope	: this
				,handler: this._onBtnLimpaFiltroClick	
			});
			
			return [{
				 scope	: this
				,iconCls: 'ico-lupa'
				,text	: 'Filtrar' 
				,handler: this._onBtnFilterClick
			},this._btnLimpaFiltro]
		}
		
		,fitGridBody: function()
		{
			var size = this.grid.body.getSize();
			size.width -= 50;
			size.height -= 50;
			
			this.maxWidth = Math.max(this.width,size.width);
			size.width = this.minWidth = Math.min(this.width,size.width);
			
			this.maxHeight = Math.max(this.height,size.height);
			size.height = this.minHeight = Math.min(this.height,size.height);
			
			this.setSize(size);
		}
		
	//}
	
});
Ext.preg('b-gridfilter',Bt.grid.GridFilter);


Bt.grid.GridFilter.Filters = {
	
	 'text'	: { xtype:'textfield' }
	,'UF'	: { 
		 xtype	: 'b-comboestados'
		,width	: 150 
	}
};

Bt.form.ComboBox = Ext.extend(Ext.form.ComboBox, {

	
	
	//Config Options
		
		//Bt.form.ComboBox	
		 emptyOption    : undefined
		,loadMask		: true
		,grouping		: false
		,canSelectGroup	: false
		
		//super 
		,mode			: 'remote'
		,triggerAction	: 'all'
		,forceSelection	: true
		
	//}
	
	//Inits {
		
		,initEvents: function( config ) 
		{
			//super
			Bt.form.ComboBox.superclass.initEvents.call(this);
			
			this.store.on({
				 scope			: this
				,'load'			: this._onStoreLoad
				,'loadexception': this._onStoreLoadException
			});
				
			if( this.mode === 'remote' && this.loadMask)
				this.store.on('beforeload', this._onStoreBeforeLoad, this );
		}
	
	//}
	
	//Overrides {
	
		,onRender: function()
		{
			//super
			Bt.form.ComboBox.superclass.onRender.apply(this,arguments);
		
			if (this.emptyOption) 
				this._createEmptyOption();
		}
		
		,setValue: function()
		{
			if (this.emptyOption) 
				this._createEmptyOption();
				
			//super
			Bt.form.ComboBox.superclass.setValue.apply(this,arguments);	
		}
		
		,initList:function()
		{
			var cssClass = 'x-combo-list-item'
			var cssClassAditional = 'x-combo-list-item-group';
			
			if( !this.tpl && this.grouping )
				this.tpl = new Ext.XTemplate(
					'<tpl for=".">',
						'<tpl if="!isGroup">',
							'<div class="'+cssClass+'">{'+ this.displayField +'}</div>',
						'</tpl>',
						'<tpl if="isGroup">',
							'<div class="'+cssClass+' '+cssClassAditional+'">{'+ this.displayField +'}</div>',
						'</tpl>',
					'</tpl>'
				);
			
			//super
			Bt.form.ComboBox.superclass.initList.apply(this,arguments);	
			
			//event
			this.mon(this.view, 'beforeclick', this._onViewBeforeClick, this);
		}
		
		,onViewOver : function(e, t)
		{
			var elOpt= Ext.get(t);
	
			if( !this._testSelectionGroup( elOpt ) )
				return false;
			
			Bt.form.ComboBox.superclass.onViewOver.apply(this,arguments);
		}
		
	//}
	
	//Acessores {
		
		
		,setMode:function( mode, preventQuery )
		{
			this.mode = mode;
			
			if(this.initialConfig.queryDelay === undefined)
				this.queryDelay = (this.mode == 'local')?10:500;
			
			if(this.initialConfig.minChars === undefined)
				this.minChars = (this.mode == 'local')?0:4;
		
			if( mode === 'local' && !preventQuery && this.lastQuery !== this.allQuery )	
			{
				delete this.lastQuery;
				this.initQuery();	
			}
		}
	
	//}
	
	//Listeners {
	
		,_onStoreBeforeLoad: function()
		{
			if(this.rendered)
				this.mask();
			else
				this.on('render',this.mask,this,{single:true});
		}
	
		,_onStoreLoad : function () 
		{
			if (this.emptyOption) 
				this._createEmptyOption();
				
			if(this.loadMask)
			{
				if(this.rendered)
					this.unmask();
				else
					this.un('render',this.mask,this);
			}
		}
		
		,_onStoreLoadException: function()
		{
			if(this.loadMask)
			{
				if(this.rendered)
					this.unmask();
				else
					this.un('render',this.mask,this);
			}
		}
		
		,_onViewBeforeClick : function( dataView , index , node, selections  )
		{
			var node = Ext.get(node);
	
			if( !this._testSelectionGroup( node ) )
				return false;
	
			return true;
		}
		
	//}
	
	//Demais m�todos {
	
			
		,toLabel: function()
		{
			this.setEditable(false);
			this.el.un('mousedown', this.onTriggerClick,  this);
			this.onTriggerClick = Ext.emptyFn;
			this.trigger.hide();
			
			this.el.applyStyles({			
				'background':'transparent'
				,'border'	:'none'	
				,'cursor'	:'default'	
			});
		}
	
		,mask: function()
		{
	 		this.wrap.setLoading(true,{simple:true});
		}
		
		,unmask:function()
		{
			this.wrap.setLoading(false);	
		}
		
		,expand: function( force )
		{
			if( force === true )
			{
				this.onFocus({});
				
				Bt.form.ComboBox.superclass.expand.call(this);
				
	         	this.restrictHeight();
				this.el.dom.select();
				
				if(!this.selectByValue(this.value, true))
				{
					this.select(0, true);
				}
				
				this.el.focus();
			}
			else
			{
				Bt.form.ComboBox.superclass.expand.call(this);
			}
		}
	
		,createOption: function( obj )
		{
			var generateID		= obj.generateID;
			var preventSelect 	= obj.preventSelect; 
			
			if(!obj[this.valueField]	)obj[this.valueField	] = obj.value;
			if(!obj[this.displayField]	)obj[this.displayField	] = obj.display;
			
			delete obj.value;
			delete obj.display;
			delete obj.generateID
			delete obj.preventSelect;
			
			var rec = new this.store.recordType(obj, generateID ? undefined : obj[this.valueField]);
			this.store.add(rec);
			
			if(!preventSelect)
				this.setValue(obj[this.valueField]);
		}
		
		,_createEmptyOption: function()
		{
			var emptyValue = 0;
			var emptyText  = this.emptyOption;
			  
			if (typeof(this.emptyOption) === 'object')
			{
				emptyValue = this.emptyOption.value;
				emptyText = this.emptyOption.text;
			}
			
			if( this.store.findExact(this.valueField,emptyValue) !== -1 )
				return;
			
			this.emptyText = emptyText;
				
			var obj = Ext.decode('{'+this.valueField+':'+emptyValue+','+ this.displayField +':"'+emptyText+'"}');
			var record = new Ext.data.Record(obj);
			
			// insere o novo registro na primeira posi��o
			this.store.insert(0, record);
		}
		
		,_testSelectionGroup : function( mix )
		{
			if(!this.grouping)
				return true;
			
			var isGroupOption = false;
				
			//if the param is an Ext.Element, check the class
			if (mix.hasClass && mix.hasClass('x-combo-list-item-group')) {
				isGroupOption = true;
				
			//Otherwise test if it's a record
			}else if (mix.get && mix.get('isGroup') === true){
					isGroupOption = true;
			}
			
			if( !isGroupOption || (isGroupOption && this.canSelectGroup) )
				return true;
				
			return false;
		}
			
	//}
	
}); 

Ext.reg('bt-combo',Bt.form.ComboBox);
Bt.form.ComboEstados = Ext.extend(Bt.form.ComboBox,{

	constructor: function()
	{
		this.store = [
			['AC','Acre'],['AL','Alagoas'],['AM','Amazonas'],['AP','Amap&#225;'],['BA','Bahia'],
			['CE','Cear&#225;'],['DF','Distrito Federal'],['ES','Esp&#237;rito Santo'],['GO','Goi&#225;s'],['MA','Maranh&#227;o'],['MG','Minas Gerais'],
			['MS','Mato Grosso do Sul'],['MT','Mato Grosso'],['PA','Par&#225;'],['PB','Para&#237;ba'],['PE','Pernambuco'],['PI','Piau&#237;'],
			['PR','Paran&#225;'],['RJ','Rio de Janeiro'],['RN','Rio Grande do Norte'],['RO','Rond&#244;nia'],['RR','Roraima'],['RS','Rio Grande do Sul'],
			['SC','Santa Catarina'],['SE','Sergipe'],['SP','S&#227;o Paulo'],['TO','Tocantins']
		]
		Bt.form.ComboEstados.superclass.constructor.apply(this,arguments);
	}
});

Ext.reg('b-comboestados',Bt.form.ComboEstados);
Bt.form.MoneyField = function(config)
{
    var defConfig = {
        autocomplete: 'off',
        allowNegative: true,
        format: 'BRL',
        currency: 'R$',
        showCurrency: true
    };
	
    Ext.applyIf(config, defConfig);
	
	if(!config.emptyText)
		config.emptyText = config.currency + ' 0,00';
	
    Bt.form.MoneyField.superclass.constructor.call(this, config);
};

Ext.extend(Bt.form.MoneyField, Ext.form.TextField, {
	
	initComponent: function()
	{
		if(!this.hiddenName){
            this.hiddenName = this.name;
			delete this.name;
        }
		
		switch (this.format) 
		{
            case 'USD':
                this.currencyPosition = 'left';
                this.currency = '$';
                break;
                
			case 'BRL' :	
            default:
                this.currency = 'R$ ';
                this.currencyPosition = 'left';
                break;
        }
			
		//super
		Bt.form.MoneyField.superclass.initComponent.call(this);
	}
	
    ,initEvents: function(){
        Bt.form.MoneyField.superclass.initEvents.call(this);
        this.el.on("keydown", this.stopEventFunction, this);
        this.el.on("keyup", this.mapCurrency, this);
        this.el.on("keypress", this.stopEventFunction, this);
    },
	
	setValue: function(v)
	{
		//transforma valor
		v = parseFloat(v);
		v = isNaN(v) ? "0,00" : v.toFixed(2);
		v += "";
		v = v.replace('.',',');
		
		//separa parte inteira e decimal
		v = v.split(',');
		var parteInt = v[0];
		var parteDec = v[1]
		var v = '';
		
		//coloca '.' na parte inteira a cada 3 digitos
		for(var i = 0, l=parteInt.length, l2=l-1 ; i <= l ; i++ )
		{
			if( i!== 0 && i % 3 === 0 )
				v = '.' + v;
				
			v = parteInt.charAt(l2-i) + v;
		}
		
		//junta novamente parte inteira e decimal
		v = v + ',' + parteDec;
		
		//atribui ao hidden
		if(this.hiddenField)
			this.hiddenField.value = v;
			
		//adiciona currency
		if( this.showCurrency )
		{
			if( this.currencyPosition == 'left' )
			{
				v = this.currency + v;
			}	
			else
			{
				v += this.currency;
			}
		}
		
		//atribui
		Bt.form.MoneyField.superclass.setValue.call(this,v);
	},
	
	onRender: function()
	{
		Bt.form.MoneyField.superclass.onRender.apply(this, arguments);
		
		if(this.hiddenName){
            this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
                    id: (this.hiddenId||this.hiddenName)}, 'before', true);

            // prevent input submission
            this.el.dom.removeAttribute('name');
        }
	},
	
	// private
    onEnable : function(){
        Bt.form.MoneyField.superclass.onEnable.apply(this, arguments);
        if(this.hiddenField){
            this.hiddenField.disabled = false;
        }
    },

    // private
    onDisable : function(){
        Bt.form.MoneyField.superclass.onDisable.apply(this, arguments);
        if(this.hiddenField){
            this.hiddenField.disabled = true;
        }
    },
	
	// inherit docs
    getName: function(){
        var hf = this.hiddenField;
        return hf && hf.name ? hf.name : this.hiddenName || Bt.form.MoneyField.superclass.getName.call(this);
    },
	
	clearValue : function(){
        if(this.hiddenField){
            this.hiddenField.value = '';
        }
		
		Bt.form.MoneyField.superclass.clearValue.apply(this, arguments);
    },
	
	// private
    initValue : function()
	{
        Bt.form.MoneyField.superclass.initValue.call(this);
		
        if(this.hiddenField)
		{
            this.hiddenField.value =
                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
                Ext.isDefined(this.value) ? this.value : '';
        }
    },
    
    KEY_RANGES: {
        numeric: [48, 57],
        padnum: [96, 105]
    },
    
    isInRange: function(charCode, range){
        return charCode >= range[0] && charCode <= range[1];
    },
    
    formatCurrency: function(evt, floatPoint, decimalSep, thousandSep){
        floatPoint = !isNaN(floatPoint) ? Math.abs(floatPoint) : 2;
        thousandSep = typeof thousandSep != "string" ? "," : thousandSep;
        decimalSep = typeof decimalSep != "string" ? "." : decimalSep;
        var key = evt.getKey();
        
        if (this.isInRange(key, this.KEY_RANGES["padnum"])) {
            key -= 48;
        }
        
        this.sign = (this.allowNegative && (key == 45 || key == 109)) ? "-" : (key == 43 || key == 107 || key == 16) ? "" : this.sign;
        
        var character = (this.isInRange(key, this.KEY_RANGES["numeric"]) ? String.fromCharCode(key) : "");
        var field = this.el.dom;
        var value = (field.value.replace(/\D/g, "").replace(/^0+/g, "") + character).replace(/\D/g, "");
        var length = value.length;
        
        if (character == "" && length > 0 && key == 8) {
            length--;
            value = value.substr(0, length);
            evt.stopEvent();
        }
        
        if (field.maxLength + 1 && length >= field.maxLength) 
            return false;
        
        length <= floatPoint && (value = new Array(floatPoint - length + 2).join("0") + value);
        for (var i = (length = (value = value.split("")).length) - floatPoint; (i -= 3) > 0; value[i - 1] += thousandSep) 
            ;
        floatPoint && floatPoint < length && (value[length - ++floatPoint] += decimalSep);
        field.value = (this.showCurrency && this.currencyPosition == 'left' ? this.currency : '') +
        (this.sign ? this.sign : '') +
        value.join("") +
        (this.showCurrency && this.currencyPosition != 'left' ? this.currency : '');
		
		if(this.hiddenField){
            this.hiddenField.value = value.join("");
        }
		
    },
    
    mapCurrency: function(evt){
        switch (this.format) {
            case 'BRL':
                this.formatCurrency(evt, 2, ',', '.');
                break;
                
            case 'USD':
                this.formatCurrency(evt, 2);
                break;
                
            default:
                this.formatCurrency(evt, 2);
        }
    },
    
    stopEventFunction: function(evt){
        var key = evt.getKey();
        
        if (this.isInRange(key, this.KEY_RANGES["padnum"])) {
            key -= 48;
        }
        		
        if (((key >= 41 && key <= 122) || key == 32 || key == 8 || key > 186) && (!evt.altKey && !evt.ctrlKey)) {
            evt.stopEvent();
        }
    },
    
    getCharForCode: function(keyCode){
        var chr = '';
        switch (keyCode) {
            case 48:
            case 96: // 0 and numpad 0
                chr = '0';
                break;
                
            case 49:
            case 97: // 1 and numpad 1
                chr = '1';
                break;
                
            case 50:
            case 98: // 2 and numpad 2
                chr = '2';
                break;
                
            case 51:
            case 99: // 3 and numpad 3
                chr = '3';
                break;
                
            case 52:
            case 100: // 4 and numpad 4
                chr = '4';
                break;
                
            case 53:
            case 101: // 5 and numpad 5
                chr = '5';
                break;
                
            case 54:
            case 102: // 6 and numpad 6
                chr = '6';
                break;
                
            case 55:
            case 103: // 7 and numpad 7
                chr = '7';
                break;
                
            case 56:
            case 104: // 8 and numpad 8
                chr = '8';
                break;
                
            case 57:
            case 105: // 9 and numpad 9
                chr = '9';
                break;
                
            case 45:
            case 189:
            case 109:
                chr = '-';
                break;
                
            case 43:
            case 107:
            case 187:
                chr = '+';
                break;
                
            default:
                chr = String.fromCharCode(keyCode); // key pressed as a lowercase string
                break;
        }
        return chr;
    }
});
Ext.reg('moneyfield', Bt.form.MoneyField);

Bt.form.VMask = {
	 cnpj		: '99.999.999/9999-99'
	,cep		: '99999-999'
	,telefone 	: '(99)9999-9999'
	,cpf		: '999.999.999-99'
};


(function()
{
	var url = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
	
	Ext.apply(Ext.form.VTypes,{
		
		 'urlText'	: 'URL inv�lida'
		,'url'		: function(v)
		{
			return url.test(v);
		}
	
		,'cnpjText'	: 'CNPJ inv&#225;lido'
		,'cnpj'		: function (cnpj) 
		{
			if(cnpj.trim().length === 0)
				return true;
			
			if (cnpj.length < 18)
			{
				return false;
			} 
			else if ((cnpj.charAt(2) != ".") || (cnpj.charAt(6) != ".") || (cnpj.charAt(10) != "/") || (cnpj.charAt(15) != "-"))
			{
				return false;
			}
			
			//retira separadores
			cnpj = cnpj.replace(/[.\-\/]/gi,"");
	
			var a = [];
			var b = new Number;
			var c = [6,5,4,3,2,9,8,7,6,5,4,3,2];
			for (i=0; i<12; i++)
			{
				a[i] = cnpj.charAt(i);
				b += a[i] * c[i+1];
			}
	
			if ((x = b % 11) < 2) 
			{ 
				a[12] = 0 
			} 
			else 
			{ 
				a[12] = 11-x 
			}
	
			b = 0;
			for (y=0; y<13; y++) 
			{
				b += (a[y] * c[y]);
			}
	
			if ((x = b % 11) < 2) 
			{ 
				a[13] = 0; 
			} 
			else 
			{
				 a[13] = 11-x; 
			}
	
			if ((cnpj.charAt(12) != a[12]) || (cnpj.charAt(13) != a[13]))
				return false
			
			return true;
		}
	
		,'cpfText'	: 'CPF inv&#225;lido'
		,'cpf'		: function( cpf )
		{
			//retira separadores
			cpf = cpf.replace(/[.\-\/]/gi,"");
			
			//tamanho 11
            if (cpf.length !== 11) 
                return false;
				
			//somente numeros
            if (/\D/.test(cpf)) 
                return false
			
			//sequencias proibidas	 
            if( cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || 
				cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || 
				cpf == "88888888888" || cpf == "99999999999") 
			{
                return false
            }
			
			
            var a = [];
            var b = 0;
            var c = 11;
            for (i = 0; i < 11; i++) 
			{
                a[i] = cpf.charAt(i);
                if (i < 9) 
                    b += (a[i] * --c);
            }
            if ((x = b % 11) < 2) 
			{
                a[9] = 0
            }
            else 
			{
                a[9] = 11 - x
            }
            b = 0;
            c = 11;
            for (y = 0; y < 10; y++) 
                b += (a[y] * c--);
            if ((x = b % 11) < 2) {
                a[10] = 0;
            }
            else {
                a[10] = 11 - x;
            }
			
			//digito verificar com problema
            if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])) {
                return false;
            }
			
            return true;
		}
		
		,'passwordText' : 'Senhas devem ser iguais'
		,'password' 	: function(val, field) 
		{
			var cmpPass = 	!field.initialPassField || field.initialPassField == 'previous' ? field.previousSibling() :
							(Ext.getCmp(field.initialPassField) || field.ownerCt.getComponent(field.initialPassField));
			
            return (val == cmpPass.getValue());
	    }
	})
}()); 
